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?