簡體   English   中英

如何允許C#方法的通用類型參數接受空參數?

[英]How to allow a generic type parameter for a C# method to accept a null argument?

private static Matcher<T> EqualTo<T>(T item)
{
    return new IsEqual<T>(item);
}

如何修改上面的方法定義,以使以下內容有效/允許。

EqualTo("abc");
EqualTo(4);
EqualTo(null); // doesn't compile. EqualTo<string>(null) does

嘗試移植一些Java代碼,其中T參數的null似乎是可接受的值。


更新資料
謝謝:所有的答案-特別是Eamon和Jason。 我不想讓方法調用煩擾類型推斷。 以下過載對其進行了修復。

    private static Matcher<object> EqualTo(object item)
    {
        return EqualTo<object>(item);
    }  

實際上,上述問題是一個更大難題的一部分。 最終目標是使以下工作正常進行。

        this.AssertThat(null, EqualTo(null));
        this.AssertThat(null, Not(EqualTo("hi")));
        this.AssertThat("hi", Not(EqualTo(null)));

應用了相同的修補程序。RFC (忽略丑陋的擴展方法部分-這是另一個問題。想要在所有測試夾具中都使用這些方法而無需繼承。)

public static void AssertThat<T>(this object testFixture, object actual, Matcher<T> matcher, string message = "")
{
  AssertThat(anyObject, (T)actual, matcher, message);
}

public static void AssertThat<T, TSuper>(this object testFixture, T actual, Matcher<TSuper> matcher, string message = "") where T : TSuper
{
  ... check and assert

請考慮以下方法:

public bool IsNullString<T>(T item) {
    return typeof(T) == typeof(string) && item == null;
}

是的,這是一個可悲的愚蠢方法,在這里使用泛型是沒有意義的,但是稍后您會明白這一點。

現在考慮

bool first = IsNullString<string>(null);
bool second = IsNullString<Foo>(null);

bool third = IsNullString(null);

在第一個和第二個中,編譯器可以清楚地區分T的類型(無需推斷)。 第三,編譯器如何推斷T是什么? 特別是,它無法區分T == stringT == Foo ,或其他任何類型。 因此,編譯器必須給您一個編譯時錯誤。

如果您想解決這個問題,則需要強制為null

EqualTo((object)null);

或明確說明類型

EqualTo<object>(null)

或定義重載

private static Matcher<object> EqualTo(object item) {
    return new IsEqual<object>(item);
}

如果沒有明確指定T或進行強制轉換,則無法實現。 泛型是編譯時的構造,因此,如果編譯器無法在編譯時弄清類型,那么它將無法編譯(如您所見)。

由於您無法完全執行您想做的事情,如何定義一個EqualTo(object)重載方法? 那應該允許您需要的語法。

您可以使用以下語法解決此限制:

EqualTo("abc");
EqualTo(4);
EqualTo(default(object));
//equivalently:
EqualTo((object)null);

如果未設置,則default(T)是類型T的字段具有的值。 對於引用類型,它為null ;對於值類型,它本質上是零字節填充的內存(...這可能意味着不同類型的事物不同,但通常意味着某種形式的零)。

如今,我嘗試在代碼中的所有位置避免使用null 它也會阻礙其他地方的類型推斷,例如使用var聲明字段和三元運算符。 例如, myArray==null ? default(int?) : myArray.Length myArray==null ? default(int?) : myArray.Length可以,但是myArray==null ? null : myArray.Length myArray==null ? null : myArray.Length無法編譯。

也許實現一個以對象為參數類型的非泛型EqualTo可以解決重寫這些代碼行的問題。

暫無
暫無

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

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