Сохраняется ли информация о необязательных ссылочных типах C # 8 в сборке .NET? - PullRequest
1 голос
/ 10 октября 2019

Будут ли потребители пакета Nuget, написанного на C # 8 со ссылочными типами, допускающими обнуляемость, видеть информацию об обнуляемости полей / параметров, определенных в этом пакете? Сможет ли компилятор C # 8 использовать эту информацию для выдачи соответствующих предупреждений?

1 Ответ

3 голосов
/ 11 октября 2019

Да, при условии, что они также используют C # 8 или более позднюю версию и имеют включенный Nullable. Это уже происходит с типами BCL.

NRT в C # 8 не вводят новый тип типа. Компилятор генерирует атрибуты NullableContext и Nullable в проектах или файлах, где включены NRT. Они используются для анализа кода и выдачи предупреждений об обнуляемости. Независимо от того, включена обнуляемость или нет, string и string? все еще одного типа, string.

NullableAttribute и C # 8 Джона Скита объясняет, как работают эти атрибуты и как они влияют на публичный API пакета, в данном случае Noda Time. Пакет был перенесен в C # 8 еще в феврале 2019 года.

Как объясняет Джон Скит:

Компилятор C # 8 создает внутренний класс NullableAttribute в сборке (что, я полагаю, неесли мы нацелены на фреймворк, который уже включает в себя такой атрибут) и применяет атрибут везде, где это уместно.

Это делает прозрачным изменение для более старых компиляторов C #

Проверьте в этом примере Sharplab.io . Следующий простой класс:

#nullable enable
using System;
public class C {
    public void M(C c) {
    }
}

Создает этот промежуточный код C #:

public class C
{
    [System.Runtime.CompilerServices.NullableContext(1)]
    public void M(C c)
    {
    }
}

Пока this :

    public C M(C? c) {
        return c ?? throw new ArgumentNullException(nameof(c));
    }

Создает этот промежуточныйC #:

    [System.Runtime.CompilerServices.NullableContext(1)]
    public C M([System.Runtime.CompilerServices.Nullable(2)] C c)
    {
        if (c != null)
        {
            return c;
        }
        throw new ArgumentNullException("c");
    }
}
...