I have a generic interface IDataAdapter<T>; implementors of the interface should be able to read POCOs with Guid IDs from a data source. IDataAdapter<T> has a method Read(Guid id) which I want to return a T?, where null indicates that no matches were found in the data source. However, even with a constraint T : notnull on IDataAdapter<T>, attempting to define this method gives the error CS8627: 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. Why am I still getting this error, even with T constrained to notnull?
Code (should be in a C# 8 environment with <Nullable>enable</Nullable>):
interface IDataAdapter<T> where T : notnull
{
T? Read (Guid id); // error CS8627
}
I think this issue is very similar to what is happening in this post.
Note that a T? where T : class and a T? where T : struct are represented very differently in the CLR. The former is just the CLR type T. There are not separate types in the CLR to differentiate between T and T?. T? in C# just adds extra compile time checking by the C# compiler. On the other hand, The latter is represented by the CLR type Nullable<T>.
So let's consider your method:
T? Read (Guid id);
How should this be represented in the CLR? What is the return type? The compiler don't know whether T is a reference type or a value type, so the compiler cannot decide whether the method signature should be:
T Read (Guid id);
or:
Nullable<T> Read (Guid id);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With