Аннотирует ли C # 8 свойства и параметры, которые можно обнулять? - PullRequest
0 голосов
/ 06 декабря 2018

Мне любопытно, как работают ссылочные типы, которые можно обнулять, не в вашей собственной кодовой базе, а с уже скомпилированной библиотекой.Сможет ли C # узнать, является ли свойство или параметр обнуляемым, возможно, проверяя наличие какого-либо добавленного компилятором атрибута?

Ответы [ 3 ]

0 голосов
/ 07 декабря 2018

Да, если библиотека была скомпилирована с использованием компилятора 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) { }
}

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

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

0 голосов
/ 11 февраля 2019

Похоже, что поведение между 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() { ... }
}

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

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

0 голосов
/ 06 декабря 2018

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

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

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

...