我在C#中读到了大约notnull个约束,上面写道"这允许值类型或不可为空的引用类型,但不允许为空的引用类型." (引用自Ian Griffiths的《Programming C#-10.0》)

我try 在以下代码中判断此约束:

MyTestClass<int?> instance1 = new MyTestClass<int?>();
MyTestClass<string?> instance2 = new MyTestClass<string?>();

public class MyTestClass<T> where T : notnull
{
    T Value { get; set; }

    public MyTestClass()
    {
        Value = default(T);
        if (Value == null)
            Console.WriteLine($"Type of T is {typeof(T)} and its default value is 'Null'");
        else
            Console.WriteLine($"Type of T is {typeof(T)} and its default value is {Value}");
    }
}

正如你所看到的,我用可空类型int?(可空值类型)和string?(可空引用类型)实例化了我的泛型类,它仍然对我有效.

它还为我打印如下输出:

Type of T is System.Nullable`1[System.Int32] and its default value is 'Null'
Type of T is System.String and its default value is 'Null'
Type of T is System.Int32 and its default value is 0
Type of T is System.String and its default value is 'Null'"

它的行为是"字符串?"作为‘字符串’,并将两者检测为不可为空. 发生这种情况的原因可能是什么?

推荐答案

如定义的那样,notnull约束"将类型参数限制为不可为空的类型.类型可以是值类型或不可空的引用类型."[1]

约束可用于可为空的启用上下文中的代码,并且在编译时判断与约束不匹配的类型参数(即string?int[]?),并创建warning而不是错误,具体而言是CS8714: Nullability of type argument doesn't match 'notnull' constraint.

因此,程序将在违反notnull约束时进行编译,但会在可能的情况下引发编译时警告.值得一提的是,它只会在可能的情况下发出警告,因为"包含非空约束的泛型声明可以在可为空的忽略上下文中使用,但编译器不强制执行该约束."[1]

因此,可以将可为空的引用类型can作为有效类型参数传递给使用notnull约束指定的类型参数,但不应如此.除非它不在#nullable enable环境中运行,否则您的演示中应该会出现警告.

资料来源:

  1. https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/where-generic-type-constraint

Csharp相关问答推荐

利用.NET 8中的AddStandardResilienceDeliveries和AddStandardHedgingDeliveries实现Resiliency

为什么EF Core 6会针对null验证Count(*)?

try 还原包时出错:Dapper已经为System.Data.SQLClient定义了依赖项''''

在LINQ Where子句中使用新的DateTime

从应用程序图API调用访问所有者字段

具有单一导航属性的EF核心一对多关系

有没有办法在WPF文本框中添加复制事件的处理程序?

需要在重新启动ApplicartionPool或IIS后启动/唤醒API的帮助

Cosmos SDK和Newtonsoft对静态只读记录的可能Mutations

如何将此方法参数化并使其更灵活?

使用泛型可空类实现接口

每个http请求需要60秒,为什么?

有没有类似于扩展元素的合并元组的语法?

在try 使用访问服务器上的文件夹时,如何解决CORS错误.NET核心API

GODOT 4向C#中的字符串参数发送信号以等待

Visual Studio,Docker容器-容器调用:连接被拒绝

如何在C# WinForm控件中使用Windows 10/11的黑暗主题?

如何在特定时间间隔运行多个后台任务?

Xamarin中出错.表单:应用程序的分部声明不能指定不同的基类

将列表转换为带有逗号分隔字符串形式的值的字典