我想创建一个通用类,该类具有类型为T
的成员。 T
可以是类、可空类、结构或可空结构。 因此基本上可以是任何东西。 这是一个简化的示例,显示了我的问题:
#nullable enable
class Box<T> {
public T Value { get; }
public Box(T value) {
Value = value;
}
public static Box<T> CreateDefault()
=> new Box<T>(default(T));
}
由于使用了新的#nullable enable
功能,我收到了以下警告:Program.cs(11,23): warning CS8653: A default expression introduces a null value when 'T' is a non-nullable reference type.
这个警告对我来说是有道理的。然后我尝试通过在属性和构造函数参数中添加?
来修复它:
#nullable enable
class Box<T> {
public T? Value { get; }
public Box(T? value) {
Value = value;
}
public static Box<T> CreateDefault()
=> new Box<T>(default(T));
}
但现在我得到了两个错误:
Program.cs(4,12): 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.
Program.cs(6,16): 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.
然而,我不想添加约束。 我不在乎 T
是一个类还是一个结构体。
一个显而易见的解决方案是在 #nullable disable
指令下包装有问题的成员。然而,像 #pragma warning disable
一样,除非必要,我想避免这样做。是否有其他方法可以让我的代码在不禁用可空性检查或 CS8653 警告的情况下编译?
$ dotnet --info
.NET Core SDK (reflecting any global.json):
Version: 3.0.100-preview4-011223
Commit: 118dd862c8
T?
的差异。为什么?我可以猜测这只会增加许多复杂性,但我也猜想您需要实际的编译器人员提供输入才能确定。对于值类型,T?
由Nullable<T>
处理,而对于引用类型,C# 8 中的T?
由具有属性的T
处理。基本上,我认为这是不受支持的。 - Lasse V. Karlsennull
分配给类型为T
的变量(当T
是引用类型时),然后使用default(T)
,这可能会为引用类型返回null
。这里没有什么神秘的。您必须选择一条路,就像Neo一样... :-) - JuanRBox<T> where T : class
和一个ValueBox<T> where T : struct
。我认为目前没有将泛型类型/方法统一到T?
和Nullable<T>
上的路径。 - Jonathon Chase