当 T 被限制为枚举时,为什么 return default(T?) 不给出空值?

Why doesn't return default(T?) give a null when T is constrained to enum?

我有一个将文本文件呈现为数据模型的解析器。有些字段是可选的,在模型中表示为空。

然而,一个奇怪的行为让我很头疼。当我具体处理 nullable 时,它​​的行为符合预期。

Foo? a = null;

...工作正常。

Foo? b = default(Foo?);

...工作也很好。 b 为空。

但是,每当我将其包装在泛型 class 中时,似乎很难以相同的方式处理泛型类型参数。

void Main()
{
    Foo? is_null = null;
    Foo? is_also_null = default (Foo?);

    Foo? does_not_work = FooClass.GetNull<Foo>();
    Foo? is_not_null = FooClass.GetDefault<Foo>();   // Should be null, AFAICT, but isn't,
    
}

public static class FooClass
{
    public static T? GetNull<T>() where T:System.Enum
    {
        return null;  //Compile error: CS0403 Cannot convert null to type parameter 'T' because it could be a non-nullable value type. Consider using 'default(T)' instead.
    }
    public static T? GetDefault<T>() where T : System.Enum
    {
        return default(T?); // Why does this not return null? Shouldn't this be the same as default(Foo?) ?
    }
}

public enum Foo
{
    one,two,three
}

我做错了什么?或者我在这里缺少什么?

基本上枚举约束:没有按预期工作; T : Enum 并不意味着它把它 当作一个原始的 - 它把它当作一个盒装值(对象),恰好是 sub-type Enum 类型(或 Enum 本身!)。强调:请记住,您可以在此处使用 GetDefault<Enum>

T? 甚至在没有支持 可空引用类型 的编译器的情况下也无法编译,并且在 NRT 支持和 NRT 禁用的情况下:它会给你一个 CS8632 警告;这意味着这里的T?指的是NRTs,不是Nullable<T>。您可以通过添加 T : struct, Enum 来解决此问题,但如果没有它:default(T?)default(T) 相同(因为 NRT 的 ? 不会更改类型语义- 只是我们是否期望空值),并且 default(T) 是零枚举。