非 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&lt;int&gt;Id 将被初始化为0,绕过我的[Required] 属性

【问题讨论】:

【参考方案1】:

从 C# 8.0 开始,您现在可以使用 where T : notnull 泛型约束来指定 T 是不可为空的类型。

【讨论】:

"包含 notnull 约束的泛型声明可以在可为空的不经意上下文中使用,但编译器不强制执行该约束。"因此,如果您不使用 nullable enable 进行编译,它不会做任何事情。 在 .NET 6 项目模板中终于默认启用了可空引用类型【参考方案2】:

应用where T : struct 应用一个通用约束,即T 是一个不可为空的值类型。由于没有不可为空的引用类型,这与简单的“所有不可为空的类型”具有完全相同的语义。可空值类型(即Nullable&lt;T&gt;)不满足struct 泛型约束。

【讨论】:

很好的解释(+1)。但我有一个问题:不是 Nullable 需要 where T : struct。不是问题。提前谢谢你。 我不知道你想问什么。 由于 Nullable 是一种值类型,将继承自 struct。正确的?如果是这样,如何指示where T : struct 排除不可为空的类型?这有意义吗?很抱歉,我无法得到它。 @Christos 它不适用于该约束,因为这是 C# 语言规范所说的应该发生的事情。注意没有struct 类型。它不是继承自的东西。这是一个概念;有些类型满足它,有些则不满足。就是这么简单。 请注意这个答案的日期,写的时候是真的。在 2019 年,c# 8.0 向 C# 添加了不可为空的引用类型。

以上是关于非 Nullable 类型的通用约束的主要内容,如果未能解决你的问题,请参考以下文章

C# 8 中 Nullable 类型和泛型的问题

C#可空类型(Nullable)

C#--可空类型(Nullable)

了解下C# 可空类型(Nullable)

检查类型是不是为 Nullable 的正确方法 [重复]

可空类型(Nullable)