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)
。真的发生了什么?
答案 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”);对于参考类型,无论如何都不能使用它。