为什么以下内容是被禁止的?
Nullable<Nullable<int>>
鉴于
struct MyNullable <T>
{
}
MyNullable<Nullable<int>>
不是
发布于 2009-03-01 09:19:06
这是因为结构约束实际上意味着空,因为'not nullable'尽管是一个结构,但也是可以为空的(可以接受值为null)。对于外部可为空的,Nullable<int>
不是一个有效的类型参数。
这在the constraints documentation中是显式的
结构,其中T:
类型参数必须是值类型。可以指定除Nullable之外的任何值类型。
有关更多信息,请参见使用可空类型(C#编程指南)。
如果你想知道它的原理,你需要实际的语言设计者对它的评论,但我找不到。然而,我会假设:
,
允许int的等价物??这只会混淆这一点,因为该语言没有提供区分可空<Nullable<null>>
和可空<null>
的方法,也没有任何明显的解决方案来解决以下问题。
Nullable<Nullable<int>> x = null;
Nullable<int> y = null;
Console.WriteLine(x == null); // true
Console.WriteLine(y == null); // true
Console.WriteLine(x == y); // false or a compile time error!
要使该返回值为真,对于涉及类型的许多操作来说,这将是非常复杂和显著的开销。
CLR中的一些类型是“特殊的”,例如字符串和原语,因为编译器和运行时对彼此使用的实现了解很多。Nullable在这方面也很特别。由于它已经在其他领域有了特殊的用例,所以where T : struct
方面并不是什么大问题。这样做的好处是在泛型类中处理结构,因为除了Nullable之外,没有一个可以与null进行比较。这意味着jit可以安全地认为t == null
总是为false。
当语言被设计成允许两个非常不同的概念相互作用时,你往往会变得奇怪、困惑或危险的边缘情况。例如,考虑Nullable和相等运算符
int? x = null;
int? y = null;
Console.WriteLine(x == y); // true
Console.WriteLine(x >= y); // false!
通过在使用struct泛型约束时防止Nullable,可以避免许多令人讨厌的(和不清楚的)边缘情况。
至于规范中要求这个from section 25.7的确切部分(重点是我的):
值类型约束指定用于类型参数的类型参数必须是值类型(§25.7.1)。具有值类型约束的任何不可为空的结构类型、枚举类型或类型参数都满足此约束。具有值类型约束的类型参数不应同时具有构造函数约束。System.Nullable类型为T。指定了不可为空值类型约束。因此,以递归方式构造的T??和Nullable**
<
**Nullable**<
**T**>>
** 是禁止的。
发布于 2009-03-01 09:10:53
我相信你只能在Nullable
中使用非空值类型。因为Nullable
本身是可以为空的,所以这种嵌套方式是被禁止的。
来自http://msdn.microsoft.com/en-us/library/kwxxazwb.aspx
公共可空(T值)
类型:t A值类型。
发布于 2009-03-01 09:45:59
Nullable很特别,因为CLR中内置了对Nullable类型的装箱和拆箱的显式支持:
如果对Nullable<T>
使用MSIL box
指令,实际上会得到一个null
作为结果。没有其他值类型会在装箱时产生null。
对拆箱也有类似和对称的支持。
https://stackoverflow.com/questions/600115
复制相似问题