Skip to content

MemberNotNullWhen null tracking not working with generics #47667

@kofifus

Description

@kofifus

Version Used: 16.8.0 Preview 2.1 <TargetFramework>net5.0</TargetFramework><LangVersion>preview</LangVersion> <Nullable>enable</Nullable>

Steps to Reproduce:

Consider first the non generic example that works correctly:

class GetResult {
    [MemberNotNullWhen(true, "Value")]
    public bool OK { get; set; }
    public Manager? Value { get; set; }
}

record Manager(int Age); 

class Archive {
  readonly Dictionary<string, Manager> Dict = new Dictionary<string, Manager>();

  public GetResult this[string key] 
    => Dict.TryGetValue(key, out var value)
          ? new GetResult {OK = true, Value = value}
          : new GetResult {OK = false, Value = null};
}

public class C {
    public void M() {
        Archive archive = new Archive();
        
        GetResult result = archive["John"];
        if (!result.OK) return;
        int age1 = result.Value.Age; // NO WARNING HERE - CORRECT
    }
}

Now almost the same code with generics:

class GetResult<T> {
    [MemberNotNullWhen(true, "Value")]
    public bool OK { get; set; }
    public T? Value { get; init; }
}

record Manager(int Age); 

class Archive {
  readonly Dictionary<string, Manager> Dict = new Dictionary<string, Manager>();

  public GetResult<Manager> this[string key] 
    => Dict.TryGetValue(key, out var value)
          ? new GetResult<Manager> {OK = true, Value = value}
          : new GetResult<Manager> {OK = false, Value = null};
}

public class C {
    public void M() {
        Archive archive = new Archive();
        
        var result = archive["John"];
        if (!result.OK) return;
        int age1 = result.Value.Age; // WARNING HERE - Dereference of a possibly null reference
    }
}

Expected Behavior:

The second generic version do not give a warning when accessing result.Value (in the same way as first non generic version)

Actual Behavior:

The second generic version gives a "Dereference of a possibly null reference" warning when accessing result.Value

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions