Принудительно использовать REAL необнуляемый тип ссылки на строку - PullRequest
5 голосов
/ 27 января 2020

Я только что попробовал новый C# 8 Nullable Reference Type , который позволяет нам использовать ненулевые строки.

В моем .csproj (. NET Ядро 3.1) Я установил это:

<Nullable>enable</Nullable>

Я создал FooClass следующим образом:

public class FooClass
{
    public FooClass(string testString, DateTime testDate)
    {
        if (testString == null || testString == string.Empty)
            throw new ArgumentNullException(nameof(testString));
        else if (testDate == null)
            throw new ArgumentNullException(nameof(testDate));

        MyString = testString;
        MyDate = testDate;
    }

    public string MyString { get; }
    public DateTime MyDate { get; }
}

Однако, когда я создаю новый экземпляр моего класса в моем Main() с целевыми значениями null:

var test = new FooClass(testString:null, testDate:null);

Компилятор в порядке с параметром testString, но с параметром testDate он сообщает мне:

Аргумент 2 : невозможно преобразовать из '<null>' в 'DateTime'

Как я могу получить такое же поведение для первого аргумента?

Мой testString параметр является необнуляемым ссылочным типом, как и testDate. Поскольку я не объявил его как string?, я ожидаю, что компилятор будет вести себя одинаково для обоих параметров.

Есть ли еще одна функция, которую нужно активировать, чтобы принудительно установить real non- обнуляемые строки в C#?

1 Ответ

4 голосов
/ 27 января 2020

Вы можете добавить опцию TreatWarningsAsErrors к вашему csproj файлу

<TreatWarningsAsErrors>true</TreatWarningsAsErrors>

или добавить CS8625 предупреждение к WarningsAsErrors списку

<WarningsAsErrors>NU1605;CS8625</WarningsAsErrors>

И этот код сгенерирует ожидаемая ошибка

var test = new FooClass(testString: null, testDate: default);

ошибка CS8625: Невозможно преобразовать нулевой литерал в ненулевой ссылочный тип.

Обнуляемые ссылочные типы реализованы как аннотации типов в CLR, это может быть причиной того, что компилятор сначала показывает ошибку с testDate в исходном образце.

var test = new FooClass(testString: null, testDate: null);

Когда вы избавитесь от этой ошибки, вы увидите ожидаемое поведение с ошибочными ссылками / предупреждениями

...