Функция генерирования Generi c для типов, не допускающих значения NULL - PullRequest
0 голосов
/ 19 февраля 2020

Я пытаюсь преобразовать существующий проект в использование обнуляемых ссылочных типов свойств, используя ненулевые свойства во время инициализации .

Я использую этот подход для получения свойства, которые должны существовать:

public class Dog
{
    private Person? _person;
    public int Id { get; set; }

    public string Name { get; set; }

    public Person Person
    {
        get => _person ?? throw new InvalidOperationException(
            $"Unset property {nameof(_person)}. You probably forgot to Include it");
        set => _person = value;
    }
}

Но писать это практически для каждого свойства утомительно, поэтому я попытался сделать обобщенную c ThrowOrGet() функцию:

public static class Util
{
    public static T ThrowOrGet<T>([AllowNull] T obj)
    {
        if (obj == null)
        {
            throw new InvalidOperationException(
                $"Unset property {nameof(obj)}. You probably forgot to Include it");
        }
        return obj;
    }
}

Который используется следующим образом:

public class Dog
{
    private Person? _person;
    public int Id { get; set; }

    public string Name { get; set; }

    public Person Person
    {
        get =>  Util.ThrowOrGet(_person); ---> "Possible null reference return"
        set => _person = value;
    }
}

Но функция Util.ThrowOrGet(_person); теперь говорит, что это возможный null возврат ссылки. Если я добавлю функцию, она будет работать как задумано. Есть ли способ сделать обобщенную c функцию, которая делает это?

1 Ответ

4 голосов
/ 19 февраля 2020

Если вы собираетесь использовать ThrowOrGet только для ссылочных типов (что следует делать, так как это не имеет смысла для типов значений), тогда вы должны объявить это следующим образом:

public static T ThrowOrGet<T>(T? obj) where T : class
{
    if (obj == null)
    {
        throw new InvalidOperationException(
            $"Unset property {nameof(obj)}. You probably forgot to Include it");
    }
    return obj;
}

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

...