Does C# 8 annotate nullable properties and parameters?

Refresh

December 2018

Views

123 time

1

I'm curious about how nullable reference types work, not in your own codebase, but with an already compiled library. Will C# be able to know if a property or parameter is nullable, perhaps checking the existance of some compiler-added attribute?

3 answers

0

Похоже, что поведение изменилось между VS2019 Preview 1 и Preview 2, потенциально из-за способа, что обнуляемым контекст может быть изменен. Там нет больше не атрибут за сборки или за тип. Возможно, это будет снова измениться, конечно,

В VS2019 Preview 2, каждая часть элемента , который выражает либо обнуляемую или не обнуляемую информацию (параметры и типа возвращаемого) отдельно объясняется использование , NullableAttributeкоторый входит в сборке себя , если это необходимо. Этот атрибут имеет два конструктора:

NullableAttribute(byte)
NullableAttribute(byte[])

byteФорма используется , когда каждый аспект допустимости пустого для этого типа параметра / возврата то же самое. byte[]Используются , когда есть смесь допустимости пустых для одного элемента, из - за воспроизведенные или массивы. В обеих случаях, 1 используется для «не-обнуляемого», 2 используется для «обнуляемого». Так, например:

public class Test
{
    public string? Foo(string input) { ... }

    public List<string>? Bar() { ... }
}

компилируется:

public class Test
{
    [return:Nullable(2)]
    public string Foo([Nullable(1)] string input) { ... }

    [return: Nullable(new byte[] { 1, 2 })]
    public List<string> Bar() { ... }
}

Это позволяет любому коду следственного сборке (будь что компилятор использовать его в качестве ссылки, или другого инструмента), чтобы понять намерения на основе каждого члена.

Я написал об этом в своем блоге , но это должно быть достаточно , чтобы получить суть.

4

Да, если библиотека была собрана с помощью C # 8.0 компилятор с с обнуляемыми ссылочными типами включены, то компилятор сможет распознать, какие значения были отмечены как обнуляемые.

Например, рассмотрим следующий код:

class C
{
    string NotNullProperty { get; set; }
    string? NullProperty { get; set; }

    void M(string notNullParameter, string? nullParameter) {}
}

Она составляет примерно в:

[NonNullTypes(true)]
class C
{
    string NotNullProperty { get; set; }

    [Nullable]
    string NullProperty { get; set; }

    void M(string notNullParameter, [Nullable] string nullParameter) { }
}

Обратите внимание на то, что обнуляемым свойство и параметры помечаются как [Nullable]и весь класс помечаются как [NonNullTypes(true)], указывая , что обнуляемая ссылка типы функции включена для него.

С другой стороны, если код был скомпилирован без этой функции, она будет считаться «нуль-забывчивый». Это означает, что компилятор не будет производить предупреждения нулевых связанным, когда вы работаете с этим кодом.

1

В Take C # 8.0 для закрутки по Мадс Торгерсена (руководитель программы для языка C # в Microsoft) , он говорит:

При вызове кода, который не имел обнуляемых ссылочные типы имеют на (возможно, он был составлен до того, как функция даже существовала), то мы не можем знать, что цель этого кода было: он не различает обнуляемым и nonnullable - мы говорят, что это «нуль-забывчивый». Таким образом, мы даем ему пропуск; мы просто не предупреждают о таких вызовах.

Так нет, по-видимому, они не будут флаг, поэтому вы не получите каких-либо предупреждений компилятора. Таким образом, при потреблении кода до C # 8, похоже, вам придется сделать некоторые исследования, чтобы выяснить, может ли ссылка содержать нуль или нет, вместо того, чтобы полагаться на системы типа и компилятор, чтобы предупредить вас.