Home » c# » c# – Generic throw function for non-nullable types-Exceptionshub

c# – Generic throw function for non-nullable types-Exceptionshub

Posted by: admin February 24, 2020 Leave a comment

Questions:

I’am trying to convert an existing project to using nullable reference types properties using this:
https://docs.microsoft.com/en-us/ef/core/miscellaneous/nullable-reference-types#non-nullable-properties-and-initialization

I’am using this approach for getting properties which should exist:

 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;
        }
    }

But it’s tedious to write this for almost every property, so i tried to make a generic ThrowOrGet function:

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;
    }
}

which is used like this:

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;
    }
}

But the the function Util.ThrowOrGet(_person); now says that it’s a possible null reference return. If I inline the function it works like intended.
Is there a way to make a generic function that does this?

How to&Answers:

If you’re only going to use ThrowOrGet on reference types (which you should, as it doesn’t make sense for value types), then you should declare it like this:

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;
}

This says that the function accepts a nullable argument, and always returns a non-nullable reference. It’s better to follow this pattern than rely on the attributes, as they’re really just there for complex cases, which this is not.