Что CLR делают, когда сравнивают T с пустым указателем, и T является структурой?

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). Что действительно происходит?

8
задан dtb 19 March 2010 в 11:22
поделиться

3 ответа

Компилятор JIT в основном удаляет любые сравнения с null, если T - не нулевой тип значения, считая их все ложными. (Нулевые типы значений будут сравниваться с нулевым значением для этого типа, что, вероятно, вы и ожидаете.)

Если вы хотите, чтобы он сравнивался со значением по умолчанию, вы можете использовать:

if (EqualityComparer<T>.Default.Equals(value, default(T))
{
    ...
}
10
ответ дан 5 December 2019 в 11:23
поделиться

Если вы хотите 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 полезно только с типами значений (структурами, «встроенными элементами», отличными от строки); для ссылочных типов вы все равно не можете его использовать.

Ссылка MSDN

0
ответ дан 5 December 2019 в 11:23
поделиться

На ваш вопрос отвечает раздел 7.9.6 спецификации C#:

Если операнд параметра типа T сравнивается с null, а исполнительный тип T является типом значения, то результатом сравнения будет false.

5
ответ дан 5 December 2019 в 11:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: