非 Nullable 类型的通用约束
Posted
技术标签:
【中文标题】非 Nullable 类型的通用约束【英文标题】:Generic Constraint for Non Nullable types 【发布时间】:2015-02-13 20:31:16 【问题描述】:我有以下课程:
public class KeyDTO<T>
public T Id get; set;
到目前为止一切顺利,但我希望类型参数 T 是不可为空的类型。 我在某处读到这可能是可行的:
public class KeyDTO<T> where T : IComparable, IComparable<T>
public T Id get; set;
但是,如果我将 public T Id
更改为 public T? Id
,我会收到一个编译错误,告诉我 T
必须不可为空。
如何指定泛型类型参数必须不可为空?
编辑
我想完成此操作,因为我想使用 [Required]
属性注释我的 Id
属性,如下所示:
public class KeyDTO<T>
[Required]
public T Id get; set;
[Required]
所做的是验证模型,因此T
不能为空。
但是,如果我有KeyDTO<int>
,Id
将被初始化为0
,绕过我的[Required]
属性
【问题讨论】:
【参考方案1】:从 C# 8.0 开始,您现在可以使用 where T : notnull
泛型约束来指定 T
是不可为空的类型。
【讨论】:
"包含 notnull 约束的泛型声明可以在可为空的不经意上下文中使用,但编译器不强制执行该约束。"因此,如果您不使用nullable enable
进行编译,它不会做任何事情。
在 .NET 6 项目模板中终于默认启用了可空引用类型【参考方案2】:
应用where T : struct
应用一个通用约束,即T
是一个不可为空的值类型。由于没有不可为空的引用类型,这与简单的“所有不可为空的类型”具有完全相同的语义。可空值类型(即Nullable<T>
)不满足struct
泛型约束。
【讨论】:
很好的解释(+1)。但我有一个问题:不是 Nullablewhere T : struct
。不是问题。提前谢谢你。where T : struct
排除不可为空的类型?这有意义吗?很抱歉,我无法得到它。
@Christos 它不适用于该约束,因为这是 C# 语言规范所说的应该发生的事情。注意没有struct
类型。它不是继承自的东西。这是一个概念;有些类型满足它,有些则不满足。就是这么简单。
请注意这个答案的日期,写的时候是真的。在 2019 年,c# 8.0 向 C# 添加了不可为空的引用类型。以上是关于非 Nullable 类型的通用约束的主要内容,如果未能解决你的问题,请参考以下文章