C# 8 выдает предупреждение при возврате обнуляемого генерика c с ограничением обнуляемого - PullRequest
0 голосов
/ 07 января 2020

Этот код:

public T Foo<T>()
    where T : class?
{
    return null;
}

Выдает следующую ошибку:

Нулевой литерал вводит нулевое значение, когда 'T' является ненулевым ссылочным типом

Я не понимаю, почему мы не можем вернуть ноль, когда говорим, что T может быть обнуляемым. Если мы дополнительно попытаемся вернуть T?, мы получим ошибку о том, что T должен быть не обнуляемым.

Кажется, что невозможно иметь ограничение обнуляемости и возвращать обнуляемый результат в то же время время.

Ответы [ 2 ]

2 голосов
/ 07 января 2020

Представьте, что вы звоните:

string result = Foo<string>();

result теперь содержит null. Но это string, который не может быть обнуляем.

Компилятор предупреждает вас, что Foo<T> может быть вызвано, когда T не обнуляется, и возвращение null в этом случае будет неожиданным.

Обратите внимание, что where T : class? означает, что T может быть обнуляемым, но также может и не быть. И string, и string? разрешены. Я не верю, что есть какой-либо способ сказать «T должен быть обнуляемым».


Если вы пытаетесь сказать:

  1. T допускается обнулять
  2. Когда T не может обнуляться, этот тип все еще может возвращать null

Тогда вы можете написать:

[return: MaybeNull]
public T Foo<T>()
    where T : class?
{
    return null!;
}

SharpLab

Обратите внимание, что MaybeNull применяется только к контракту метода, а не к его телу, поэтому нам нужно вернуть null!. Однако в приведенной выше ссылке SharpLab видно, что вызывающий абонент string result = Foo<string>(); получает правильное предупреждение.

0 голосов
/ 07 января 2020

Давайте начнем с основы c. Допустим, у вас есть переменная ссылочного типа, которая позволяет ему иметь нулевое значение. Но дизайн вашей программы требует, чтобы он был не нулевым все время, если встречается нулевое значение, скорее всего, он получит NullReferenceException.

Чтобы избежать подобных проблем проектирования, были введены типы NullableReference. Означает, что для ссылочного типа разрешено иметь значение null, вы должны пометить его как Nullable, и любое использование должно проверять нулевое значение перед его использованием. Если проверка не найдена, компилятор выдаст предупреждение.

Если вы прочитаете эту вводную статью о NullableReferenceTypes Вы получите полное представление о том, какова цель этой новой функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...