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