Как подавить возможные предупреждения о пустых ссылках - PullRequest
0 голосов
/ 23 апреля 2020

Я играю с обнуляемыми типами в c# 8 и обнаружил проблему, которая меня беспокоит. Предположим, у меня есть метод, который принимает обнуляемый параметр. Когда параметр имеет значение null, я хочу создать исключение c. Но я хочу, чтобы метод был чистым и проверял параметр где-то еще. Метод check вызывает исключение, поэтому после метода параметр не может иметь значение null. К сожалению, компилятор этого не видит и выдает предупреждения у меня. Вот метод:

    public void Foo(string? argument)
    {
        GuardAgainst.Null(argument, nameof(argument));
        string variable = argument; // <-- Warning CS8600  Converting null literal or possible null value to non - nullable type
        var length = argument.Length; //<--Warning CS8602  Dereference of a possibly null reference
    }

Вот метод проверки:

    public static void Null(string? text, string paramName)
    {
        if (text == null)
            throw new ArgumentNullException(paramName);
    }

Теперь я могу отключить предупреждение следующим образом:

#pragma warning disable CS8602
var length = argument.Length;
#pragma warning restore CS8602

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

Ответы [ 2 ]

1 голос
/ 25 апреля 2020

Это делает то, что вы хотите:

public static void Null([NotNull] string? text, string paramName)
{
    if (text == null)
        throw new ArgumentNullException(paramName);
}

Атрибут [NotNull] указывает анализу, что после вызова этого метода text не будет null.

Это означает, что вам не нужен оператор !, который намного чище и естественнее.

void M(string? argument)
{
    GuardAgainst.Null(argument, nameof(argument));
    string variable = argument; // no warning
    // ...
}

Представьте, что оператор ? означает две вещи: 1) значение может быть NULL до вызова, и 2) значение может быть NULL после. Другой способ написать это [AllowNull, MaybeNull]. Отсутствие ? в обнуляемом контексте в равной степени означает [DisallowNull, NotNull]. В случае вашего Null метода мы получаем [AllowNull, NotNull] из-за ручной спецификации NotNull.

0 голосов
/ 23 апреля 2020

Хорошо, похоже, есть действительно простое решение - the! оператор Вы должны использовать его один раз после охраны, а затем он считается ненулевым:

public void Foo(string? argument)
{
    GuardAgainst.Null(argument, nameof(argument));
    var length = argument!.Length; 
}
...