Skip to content

ContiguousMap.TryGetValue lacks [MaybeNullWhen(false)], so using value after a miss compiles with no warning and throws NullReferenceException #96

Description

@matt-edmondson

What's wrong

ContiguousMap<TKey, TValue>.TryGetValue(TKey key, out TValue value) (Containers/ContiguousMap.cs ~line 438) sets value = default! on a miss, but its out parameter has no [MaybeNullWhen(false)]. Its siblings InsertionOrderMap and OrderedMap do carry the attribute (under #if NET5_0_OR_GREATER), and CompatibilitySuppressions.xml lists theirs but not this one.

Repro (verified: compiled and ran against current main, <Nullable>enable</Nullable>)

var m = new ContiguousMap<string, string>();
if (!m.TryGetValue("x", out string v))
    Console.WriteLine(v.Length); // no warning; NullReferenceException at runtime

The same code with InsertionOrderMap<string, string> gets a CS8600 warning, as it should.

Why it matters

Nullable flow analysis is wrong for one of the three map types. A caller that switches from InsertionOrderMap to ContiguousMap for performance silently loses the null-safety check. The code also doesn't match IDictionary<TKey, TValue>.TryGetValue, which is annotated [MaybeNullWhen(false)].

Suggested fix

Copy the pattern from InsertionOrderMap.TryGetValue:

public bool TryGetValue(TKey key,
#if NET5_0_OR_GREATER
	[MaybeNullWhen(false)]
#endif
	out TValue value)

Then add the matching entry to CompatibilitySuppressions.xml, the same way the other two maps did.

Acceptance criteria

  • The repro produces a nullable warning on NET5+ targets.
  • Package validation passes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions