I'm trying to return a value of type A?
from a method Value
. The method returns null
conditionally as I'm trying to shield the caller from obtaining a value A
in some cases (without throwing exceptions):
public class Container<A>
{
private readonly A? _value;
public readonly bool ShouldBeNull;
public A? Value => ShouldBeNull ? null : _value;
public Container(A value, bool shouldBeNull)
{
ShouldBeNull = shouldBeNull;
_value = shouldBeNull ? default(A) : value;
}
}
I would expect the code to compile: the return type is explicitly marked as nullable (A?
) meaning the caller can expect the return type to be null. The code does not compile however with error:
Cannot convert null to type parameter 'A' because it could be a non-nullable value type. Consider using 'default(A)' instead.
If I constrain type A
to be a value type (where A : struct
), the code compiles. But what I don't understand, is that if I constrain type A
to be a reference type (where A : class
) the code compiles as well.
If this is the case, why does above code snippet not work with no constraints? Is there any way to make the snippet compile with A
being either a value or a reference type?
This question was answered in a different form here: How can I return NULL from a generic method in C#?. However, I would like to find why the snippet doesn't work. If the compiler can make the snippet work in case of a value or reference type, why can't it work for both?