c# 8 non-nullable types и null!

126
16 ноября 2020, 20:20

По мотивам этого вопроса

Есть старый код, который перевожу на c#8 и там есть методы

void MethodName<T>(T value) => ...
и много вызовов вида
MethodName(null);

который может принимать как классы, так и структуры, а значит мы не можем сделать так

 void MethodName<T?>(T? value) => ...

потому что потребует указания типа T, а мы не можем указать where T: class, struct

Приходится давить варнинг при вызове

#nullable disable
MethodName(null)
#nullable enable

Но оказалось что работает и так

MethodName(null!)

Это вообще нормально? Это недоработка компилятора (бета все-таки)? Или же ! означает не просто "уверен тут не null", а более широкое "с этим значение все хорошо, проходи мимо"?

Answer 1

Согласно одному из примеров в документации, постфиксный оператор ! может использоваться, чтобы показать вашу осведомленность об использовании нулевой ссылки (в том числе и представленной непосредственно литералом null).

! (null-forgiving) operator (C# reference)

One of the use cases of the null-forgiving operator is in testing the argument validation logic. For example, consider the following class:

#nullable enable
public class Person
{
    public Person(string name) => Name = name ?? throw new ArgumentNullException(nameof(name));
    public string Name { get; }
}

Using the MSTest test framework, you can create the following test for the validation logic in the constructor:

[TestMethod, ExpectedException(typeof(ArgumentNullException))]
public void NullNameShouldThrowTest()
{
    var person = new Person(null!);
}

Without the null-forgiving operator, the compiler generates the following warning for the preceding code: Warning CS8625: Cannot convert null literal to non-nullable reference type. With the use of the null-forgiving operator, you let the compiler know that passing null is expected and shouldn't be warned about.

Перевод последнего абзаца:

При отсутствии оператора, допускающего значение null, компилятор сгенерирует следующее предупреждение: Warning CS8625: Cannot convert null literal to non-nullable reference type. С помощью использования этого оператора Вы даёте компилятору знать о том, что передача литерала null осознана и не должна вызывать беспокойства.

Так что это не недоработка компилятора, а всего лишь один из вариантов использования. Например, для проверки поведения метода в юнит-тестировании.

READ ALSO
Автозагрузка DataGridView в C#

Автозагрузка DataGridView в C#

Есть поле DataGridViewКак реализовать автозагрузку данных в это поле при запуске программы?

125
Не могу подключить Vk Api для .net

Не могу подключить Vk Api для .net

Visual Studio 2013В Package Manager Console пишу "Install-Package VkNet"

132
Нейронная сеть очень долго работает при увеличении размера сети

Нейронная сеть очень долго работает при увеличении размера сети

Сделал простую нейронную сеть на C#Все работает нормально с маленьким примером, а если я создаю 10 входных нейронов да еще скрытых слоев 2

152
Реализация двойного прыжка

Реализация двойного прыжка

Собственно в названии и заключается проблемаКод следующий:

100