将T与null进行比较时,CLR会做什么,而T是结构?

时间:2010-03-19 11:20:34

标签: c# generics clr

private static void SaveOrRemove<T>(string key, T value)
{
    if (value == null)
    {
        Console.WriteLine("Remove: " + key);
    }

    //...
}

如果我将0传递给值SaveOrRemove("MyKey", 0),则条件value == null为假,则CLR不会产生value == default(T)。真的发生了什么?

3 个答案:

答案 0 :(得分:10)

当T是非可空值类型时,JIT编译器基本上删除了与null的任何比较,假设它们都是false。 (可以为空的值类型将与该类型的空值进行比较,这可能与您的预期相符。)

如果希望将其与默认值进行比较,则可以使用:

if (EqualityComparer<T>.Default.Equals(value, default(T))
{
    ...
}

答案 1 :(得分:5)

您的问题在C#规范的第7.9.6节中得到了解答:

  

如果是类型参数类型的操作数   将T与null和运行时进行比较   T的类型是值类型,结果   这种比较是错误的。

答案 2 :(得分:0)

如果你想要default(T),你必须说出来,而不是null,它有自己的含义。如果您希望能够实际传入null代替值类型,则应使用Nullable<T>代替。

所以,你的代码将成为:

private static void SaveOrRemove<T>(string key, Nullable<T> value)
{
    if (!value.HasValue()) // is null
    {
        Console.WriteLine("Remove: " + key);
    }
    else
    {
        T val = value.Value;
        // ...
    }
}

请注意Nullable<T>仅适用于值类型(结构,字符串以外的“builtins”);对于参考类型,无论如何都不能使用它。

MSDN link