非可空类型的通用约束

Mat*_*ero 12 .net c# generics types interface

我有以下课程:

public class KeyDTO<T>
{
     public T Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止一切顺利,但我希望类型参数T是一个非可空类型.我在某处读过这可能是可行的:

public class KeyDTO<T> where T : IComparable, IComparable<T>
{
     public T Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我public T Id改为public T? Id,我会收到编译错误,告诉我T必须是不可为空的.

如何指定泛型类型参数必须是非可空的?

编辑

我想完成这个,因为我想Id[Required]属性注释我的属性,如下所示:

public class KeyDTO<T> {
    [Required]
    public T Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

什么[Required]是验证模型,因此T不能为空.

但是,如果我有KeyDTO<int>,Id将被初始化为0,绕过我的[Required]属性

nal*_*lka 36

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

  • “包含 notnull 约束的通用声明可以在可为 null 的不经意上下文中使用,但编译器不会强制执行该约束。” 因此,如果您没有使用“可空启用”进行编译,它将不会执行任何操作。 (5认同)

Ser*_*rvy 22

应用where T : struct应用作为T非可空值类型的通用约束.由于没有非可空引用类型,因此它具有与"所有非可空类型"完全相同的语义.可空值类型(即Nullable<T>)不满足struct通用约束.

  • 请注意此答案上的日期,它在撰写时是正确的。2019 年,c# 8.0 向 C# 添加了不可为 null 的引用类型。 (6认同)
  • 我不知道你想问什么。 (3认同)
  • 由于 Nullable 是值类型,因此将从结构继承。正确的?如果是这样,如何指示 `where T : struct` 排除不可为空的类型?这有意义吗?我很抱歉,但我无法得到它。 (2认同)