簡體   English   中英

通用子類和類型推斷-這是唯一的方法嗎?

[英]Generic child class and type inference - is this the only way?

更新:我最終在C#中使用了有關錯誤處理的功能方法的本文http://enterprisecraftsmanship.com/2015/03/20/functional-c-handling-failures-input-errors/

我有一個非泛型基類和一個繼承該基類的泛型類。 它們的目的是為“成功或失敗”的想法建模-有時某些情況將返回“我成功”結果,而有時某些情況將返回“我成功,這就是結果”,盡管這與問題。

public class OperationResult
{
    public bool Successful { get; protected set; }
    public string FailureMessage { get; protected set; }
    public Exception Exception { get; protected set; }

    protected OperationResult() { }

    public static OperationResult Success()
    {
        Console.WriteLine(1);
        return new OperationResult()
        {
            Successful = true
        };
    }
    // not including failure part for clarity
}

public class OperationResult<T> : OperationResult
{
    public T Result { get; private set; }

    private OperationResult () { }

    public static OperationResult<T> Success(T result)
    {
        Console.WriteLine(2);
        return new OperationResult<T>()
        {
            Successful = true,
            Result = result
        };
    }
}

我現在遇到的情況是,因為兩個方法的名稱相同,所以編譯器無法再推斷類型,因此我需要指定類型。 例如:

OperationResult.Success(); // Valid
OperationResult.Success("test"); // Invalid
OperationResult<string>.Success("test"); // Valid - wouldn't usually need to specify T

我忍不住覺得自己做錯了什么,或者有更好的方法可以做到這一點。

  1. 有沒有辦法讓編譯器在不指定我的情況下仍然推斷類型?
  2. 這是我第一次看到Thing<T>.SomeMethod()語法(不帶方括號() )-我Thing<T>.SomeMethod()是完全錯誤的嗎?

編輯 :沒有靜態便利方法的第二次嘗試。

new OperationResult().Success();
new OperationResult<string>().Success("something was successful");

public class OperationResult
{
    public bool Successful { get; protected set; }
    public string FailureMessage { get; protected set; }
    public Exception Exception { get; protected set; }

    public OperationResult() { }

    public OperationResult Success()
    {
        Console.WriteLine(1);
        return new OperationResult()
        {
            Successful = true
        };
    }
}

public class OperationResult<T> : OperationResult
{
    public T Result { get; private set; }

    public OperationResult () { }

    public OperationResult<T> Success(T result)
    {
        Console.WriteLine(2);
        return new OperationResult<T>()
        {
            Successful = false,
            Result = result
        };
    }
}

看起來您嘗試使用繼承來實現兩種不同類型的操作。 如果我正確地理解了該應用程序,並且確實進行了編譯,那么即使只有一個有效,您也可以在任何操作上調用任一Success方法。 也就是說,一個操作將返回結果或將不返回結果。 因此,您有2種不同的操作。

編譯器問題是設計問題的征兆。

設計您的類,以便只能以正確的方式使用它們。 也就是說,永遠不要公開不應調用的方法。 這里的目的是要有2個成功方法,但只有一個有效。 那是代碼的味道。

我認為問題出在這里對繼承的不當使用。

方法:

  1. 抽象基類和2個繼承的類。 基類中沒有成功方法。
  2. 2個類,一個公共接口和2個派生接口。 在構造函數中注入通用功能。

如果您重視單元可測試的代碼,則最好使用后者。 兩者都是有效的,我稍后再做。

這是您的操作方式:

public class OperationResult
{
    public bool Successful { get; protected set; }
    public string FailureMessage { get; protected set; }
    public Exception Exception { get; protected set; }

    protected OperationResult() { }

    public static OperationResult Success()
    {
        Console.WriteLine(1);
        return new OperationResult() { Successful = true };
    }

    public static OperationResult<T> Success<T>(T result)
    {
        Console.WriteLine(2);
        return new OperationResult<T>(result) { Successful = true };
    }
}

public class OperationResult<T> : OperationResult
{
    internal OperationResult(T result) { Result = result; }

    public T Result { get; private set; }
}

您的所有三個成功代碼行現在都可以運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM