Ilya Chernomordik
Ilya Chernomordik

Reputation: 30175

Inconsistent behavior in C# 8 nullable reference type handling with generics

I have this code:

public T? Foo<T>()
    where T : class?
{
    return null;
}

It gives an error that is logical and expected:

A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint.

Now I add one more constraint:

public T? Foo<T>()
    where T : class?, IDisposable // Could be any interface I guess
{
    return null;
}

Now interestingly enough error has just disappeared. Though it really seems to me we have conflicting constraints since interface is non-nullalbe while class? is.

Am I missing something here or is there a trouble with compiler?

Upvotes: 4

Views: 180

Answers (1)

canton7
canton7

Reputation: 42225

The generic type constraint where T : IDisposable means "T must be non-nullable and must implement IDisposable". Where you have multiple generic type constraints of differing nullabilities, the constraint overall is only nullable if all constraints are nullable.

So the fact that class? is nullable gets overridden by the fact that IDisposable is not.

You need where T : class?, IDisposable?.

Upvotes: 5

Related Questions