Search code examples
c#nullnull-coalescing-operator

Can the property be null ever or is VS wrong?


Having the following class, I protected it against null for Values.

public class Container
{
  public Guid Id { get; init; }
  public virtual IEnumerable<Measure> Measures { get; init; }
  public Dictionary<string, Measure[]> Measurement 
    => (Measures ?? Array.Empty<Measure>())
      .GroupBy(a => a.Type).ToDictionary(a => a.Key, a => a.ToArray());
}

public class Measure
{
  public string Name { get; set; }
  public string Type { get; set; }
}

For some reason, my IDE marks the coalescing as superfluous, claiming that the property will never be null (i.e. Measures??Array.Empty<Measure>() may be refactored to Measures).

public class Container
{
  public Guid Id { get; init; }
  public virtual IEnumerable<Measure> Measures { get; init; }
  public Dictionary<string, Measure[]> Measurement 
    => Measures
      .GroupBy(a => a.Type).ToDictionary(a => a.Key, a => a.ToArray());
}

When I followed that advice, a colleague pointed out that it's flawed. I agree with him but it's a bug in VS/R# is rearly a realistic explanation. More realistic is: it's us being wrong. So I sense that we're both missing something and that the IDE is right, somehow.

enter image description here

I can't explain how, though.

What I tried was to removing virtual, adding = default! and a few other alterations. Regardless, excuting in this in a fiddle, throws ArgumentNullException if the coalescing is removed.


Solution

  • The NRT document mentions:

    Any variable where the ? isn't appended to the type name is a non-nullable reference type. That includes all reference type variables in existing code when you've enabled this feature.

    Therefore, if nullable is enabled on the project, based on this standard the analyzer should assume that Measures will never be null.

    FYI, if you have not initialized the Measures property, you should see a CS8618 warning, though you can ignore it. If you want to avoid ignoring this warning, you can add "nullable" to the "Treat specific warnings as error" in the project settings to report compilation errors.