如何允许C#方法的泛型类型参数接受null参数?

Gis*_*shu 8 c# generics .net-4.0

private static Matcher<T> EqualTo<T>(T item)
{
    return new IsEqual<T>(item);
}
Run Code Online (Sandbox Code Playgroud)

如何修改上述方法定义,以使以下内容有效/允许.

EqualTo("abc");
EqualTo(4);
EqualTo(null); // doesn't compile. EqualTo<string>(null) does
Run Code Online (Sandbox Code Playgroud)

试图将一些Java代码移植null到一个似乎可接受的T参数值的地方.


更新
谢谢:所有答案 - 尤其是Eamon和Jason.我不希望方法调用打扰类型推断.以下重载修复了它.

    private static Matcher<object> EqualTo(object item)
    {
        return EqualTo<object>(item);
    }  
Run Code Online (Sandbox Code Playgroud)

实际上,上述问题是一个更大难题的一部分.最终目标是以下工作.

        this.AssertThat(null, EqualTo(null));
        this.AssertThat(null, Not(EqualTo("hi")));
        this.AssertThat("hi", Not(EqualTo(null)));
Run Code Online (Sandbox Code Playgroud)

应用相同的修复.. 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
Run Code Online (Sandbox Code Playgroud)

jas*_*son 11

请考虑以下方法:

public bool IsNullString<T>(T item) {
    return typeof(T) == typeof(string) && item == null;
}
Run Code Online (Sandbox Code Playgroud)

是的,这是一种可鄙的愚蠢方法,使用泛型在这里毫无意义,但你会在一瞬间看到这一点.

现在考虑

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

bool third = IsNullString(null);
Run Code Online (Sandbox Code Playgroud)

在第一个和第二个中,编译器可以清楚地区分类型T(不需要推断).第三,编译器如何推断出什么T是?特别是,它无法区分T == stringT == Foo/或任何其他类型.因此,编译器必须给你一个编译时错误.

如果你想解决这个问题,你需要投射 null

EqualTo((object)null);
Run Code Online (Sandbox Code Playgroud)

或明确说明类型

EqualTo<object>(null)
Run Code Online (Sandbox Code Playgroud)

或定义过载

private static Matcher<object> EqualTo(object item) {
    return new IsEqual<object>(item);
}
Run Code Online (Sandbox Code Playgroud)