Возможность внешних функций в качестве обнуляемых охранников? - PullRequest
0 голосов
/ 16 октября 2019

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

object? value = null;
if (value is null)
{
  throw new ArgumentNullException();
}
...

Они могут быть немного повторяющимися. Что мне интересно, так это то, что можно избежать написания кода такого типа для каждой переменной, но есть статическая функция void защитного типа, которая выдает исключение, если значение равно нулю, или просто возвращает, если значение не равно нулю. Или это слишком сложно для компилятора? Особенно, если это внешняя библиотека / пакет?

1 Ответ

2 голосов
/ 16 октября 2019

Есть несколько вещей, которые вы можете сделать.

Вы можете использовать [DoesNotReturnIf(...)] в своем методе защиты, чтобы указать, что он выбрасывает, если определенное условие истинно или ложно, например:

public static class Ensure
{
    public static void True([DoesNotReturnIf(false)] bool condition)
    {
        if (!condition)
        {
             throw new Exception("!!!");   
        }
    }
}

Тогда:

public void TestMethod(object? o)
{
    Ensure.True(o != null);
    Console.WriteLine(o.ToString()); // No warning
}

Это работает, потому что :

[DoesNotReturnIf(bool)]: помещается в параметр bool. Код после вызова недоступен, если параметр имеет указанное значение bool


В качестве альтернативы, вы можете объявить метод защиты следующим образом:

public static class Ensure
{
    public static void NotNull([NotNull] object? o)
    {
        if (o is null)   
        {
            throw new Exception("!!!");
        }
    }
}

И использовать его какэто:

public void TestMethod(object? o)
{
    Ensure.NotNull(o);
    Console.WriteLine(o.ToString()); // No warning
}

Это работает, потому что :

[NotNull]: Для выходов (параметры ref / out, возвращаемые значения) выход не будетбыть нулевым, даже если тип это позволяет. Для входных данных (по значениям / в параметрах) переданное значение, как известно, не равно нулю, когда мы возвращаем.

SharpLab с примерами


Конечно, реальный вопрос - , почему вы хотите это сделать. Если вы не ожидаете, что value будет null, тогда объявите его как object?, а не object - вот в чем смысл наличия NRT.

...