Search code examples
c#visual-studio.net-corevisual-studio-2022

Possible null reference assignment / pragma warning disable


I have a special generic class which contains a complicated collection of objects . I am creating an extension method to search the class to see if a specific item exists by name. It's worth noting that type T doesn't have any particular constraints. It could be a class/reference type or a numeric type or a string.

My extension method looks like this:

public static bool TryGetItem<T>(this MySpecialClass<T> msc, string name, out T item)
{
    T? i = msc.FindItemByName(name);
    if (i != null) 
    {
        item = i;
        return true;
    }
    else 
    {
        item = default(T);  //warning on this line.
        return false;
    }

In case it is not obvious, the use case for the extension method would be like:

//Example if the class is holding integers.
if (msc1.TryGetItem("somename1", out int item)
{
    //do something with 'item'
}

//Example if the class is holding MyClass1 objects
if (msc2.TryGetItem("somename2", out MyClass1 item)
{
    //do something with 'item'
}

I'm in Visual Studio 2022, using Core 6, and I have the "nullable" option enabled. As a result I get an green squiggly underline on the item = detault(T); line saying

Possible null reference assignment.

I understand why I'm getting the warning: I'm assigning default(T) to item which is not marked as nullable. But the nature of the method is that the out value will never be used if the method returns false. Obviously, VS doesn't realize this, and omitting the line causes an error, because out parameters have to be assigned to.

This is in an extension method, and I could ignore the squiggly line, but I have the null option turned on for a reason, as I believe it forces me to create more robust code. So, I wonder if I missing a better way to handle this.

Right now I am forcing VS2022 to skip the warning by wrapping the line like so to remove it from the warning list:

#pragma warning disable CS8601
    item = default(K);
#pragma warning restore CS8601

But I can't shake the feeling that I'm doing something "hacky". Is there a standard way that I should be handling this? Or is this scenario a good use of the "#pragma warning disable/restore"?


Solution

  • You should use the attribute MaybeNullWhenAttribute.

    Mark the out parameter with [MaybeNullWhen(false)]:

    public static bool TryGetItem<T>(
        this MySpecialClass<T> msc, 
        string name, 
        [MaybeNullWhen(false)] out T item
    ) {
        ...
    }
    

    While item is declared with a non-nullable type, the attributes tells the compiler that it may be null when TryGetItem returns false.

    See also this section in the docs about nullable analysis attributes.