关于C#规范中泛型值类型参数用NRT时T?类型的问询
泛型中
T?的类型规则说明 首先纠正一个误解:你代码里new Of<int>().Value的编译时类型其实是int?(也就是Nullable<int>),之所以GetType()返回System.Int32,是Nullable<T>的特殊装箱行为导致的——如果Nullable<T>实例有值,装箱时会直接转成底层值类型的实例,所以GetType()返回的是底层值类型的类型;如果实例是null(比如无参构造创建的对象,Value没赋值),调用GetType()会直接抛NullReferenceException。
回到你的核心问题:C#规范确实明确了泛型场景下T?的处理逻辑,具体规则如下:
- 在启用
#nullable enable的上下文里,T?的语义根据类型参数T的类型不同而变化:- 若
T是引用类型,T?是可空引用类型——这是编译器层面的注解,运行时类型还是T,编译器会针对空值访问做警告检查。 - 若
T是非可空值类型(比如int、DateTime),T?等价于Nullable<T>(即可空值类型)。 - 若
T本身就是可空值类型(比如int?),T?会直接简化成T——因为可空值类型不能再被修饰为可空。 - 若
T是无约束的类型参数(没有class或struct约束),T?表示“T的可空变体”:T是引用类型时为可空引用类型,T是非可空值类型时为可空值类型。
- 若
你可以通过编译时的类型检查验证这一点:
#nullable enable void Main() { var value = new Of<int>().Value; // 下面这行代码会触发编译器错误,说明value的编译时类型是int? int nonNullableInt = value; // 这行则可以正常编译 int? nullableInt = value; } class Of<T> { public T? Value; public Of(T? value) => Value = value; public Of() {} public Of<T> Create() => new Of<T>(default); }
内容的提问来源于stack exchange,提问作者Chris F Carroll
相关产品推荐
相关产品推荐

