50

The post is specific to C# 8. Let's assume I want to have this method:

public static TValue Get<TKey, TValue>(
  this Dictionary<TKey, TValue> src, 
  TKey key, 
  TValue @default
) 
=> src.TryGetValue(key, out var value) ? value : @default;

If my .csproj looks like this (i.e. C# 8 and nullable types are enabled, all warnings are errors):

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <LangVersion>8</LangVersion>
    <Nullable>enable</Nullable>
    <WarningsAsErrors>true</WarningsAsErrors>
  </PropertyGroup>
  …
</Project>

This code will produce the following build-time error:

DictionaryEx.cs(28, 78): [CS8714] The type 'TKey' cannot be used as type parameter 'TKey' in the generic type or method 'Dictionary'. Nullability of type argument 'TKey' doesn't match 'notnull' constraint.

Is there any way to specify that TKey has to be a non-nullable type?

1
  • For me this code compiles without CS8714 or any other warnings. Commented Aug 3, 2019 at 4:50

1 Answer 1

76

Ok, just found out that you can use notnull constraint:

public static TValue Get<TKey, TValue>(
    this Dictionary<TKey, TValue> src, 
    TKey key, TValue @default)
    where TKey : notnull
    => src.TryGetValue(key, out var value) ? value : @default;
Sign up to request clarification or add additional context in comments.

3 Comments

This gives an IntelliSense error "cannot resolve symbol" in VS 16.2.3, but it does compile and work anyway.
I couldn't find any documentation on this. Do we know if this is future-proof?
@NetherGranite: A year later, at least, this is now documented as part of Microsoft's Generic Type Constraint documentation in the Language Reference, as well as the Constraints on Type Parameters in the Programming Guide.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.