Home > other >  Dictionary.TryGetValue and possible 'null' warning
Dictionary.TryGetValue and possible 'null' warning

Time:01-25

I can't seem to wrap my head around the compiler's warning in this case:

using System;
using System.Collections.Generic;

#nullable enable
                    
public class Program
{
    public static void Main()
    {
        Guid guid = Guid.NewGuid();
        
        Dictionary<Guid, string> d = new();
        
        bool found = d.TryGetValue(guid, out string? str);
        
        if (found is false)
        {
            return;
        }
        
        string s = str; // WARNING: possible null value
    }
}

After all, I'm doing the found check and return if there is no value (e.g. when the out str value is null). Plus, the out parameter of the .TryGetValue method is annotated with [MaybeNullWhen(false)].

Would appreciate your help figuring our where I'm wrong in my expectations and fixing the code, thanks. Code is here.

CodePudding user response:

Basically the compiler (or language specification) isn't "smart" enough to carry the conditional processing of the return value from TryGetValue over when you use a local variable.

If you inline the TryGetValue call into the if condition, it's fine:

if (!d.TryGetValue(guid, out string? str))
{
    return;
}
        
string s = str; // No warning

It's possible that over time this will evolve to be more sophisticated, but it's relatively difficult to specify this sort of thing in a bullet-proof way.

This isn't limited to nullable reference types - there are other cases where logically code is fine from a human perspective, but the compiler will reject it. For example:

string text;
bool condition = DateTime.UtcNow.Hour == 5;
if (condition)
{
    text = "hello";
}
if (condition)
{
    Console.WriteLine(text); // Error: use of unassigned local variable
}

We know that if we get into the second if statement body, we'll also have gone into the first one so text will have been assigned a value, but the rules of the compiler don't attempt to be smart enough to spot that.

  •  Tags:  
  • Related