【问题标题】:Generic Constraint for Non Nullable types非 Nullable 类型的通用约束
【发布时间】: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] 属性

【问题讨论】:

    标签: c# .net generics types interface


    【解决方案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# 添加了不可为空的引用类型。
    猜你喜欢
    • 2012-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多