private static void SaveOrRemove<T>(string key, T value)
{
if (value == null)
{
Console.WriteLine("Remove: " + key);
}
//...
}
Если я называю передачу 0 для оценки: SaveOrRemove("MyKey", 0)
, условие value == null
ложь, затем CLR не делает a value == default(T)
. Что действительно происходит?
Компилятор JIT в основном удаляет любые сравнения с null, если T - не нулевой тип значения, считая их все ложными. (Нулевые типы значений будут сравниваться с нулевым значением для этого типа, что, вероятно, вы и ожидаете.)
Если вы хотите, чтобы он сравнивался со значением по умолчанию, вы можете использовать:
if (EqualityComparer<T>.Default.Equals(value, default(T))
{
...
}
Если вы хотите default (T)
, вы должны сказать это, а не null
, который имеет собственное значение . Если вам нужна возможность фактически передавать null
вместо типа значения, вы должны использовать вместо него Nullable
.
Итак, ваш код будет выглядеть следующим образом:
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
полезно только с типами значений (структурами, «встроенными элементами», отличными от строки); для ссылочных типов вы все равно не можете его использовать.
На ваш вопрос отвечает раздел 7.9.6 спецификации C#:
Если операнд параметра типа T сравнивается с null, а исполнительный тип T является типом значения, то результатом сравнения будет false.