基本上,为什么下面的内容在C#中是无效的?我可以找到它的许多好的用法,实际上可以通过创建我自己的可空结构类来修复它,但是C#规范(以及编译器)为什么以及如何阻止它?
下面是我所说的部分例子。
struct MyNullable<T> where T : struct
{
public T Value;
public bool HasValue;
// Need to overide equals, as well as provide static implicit/explit cast operators
}
class Program
{
static void Main(string[] args)
{
// Compiles fine and works as expected
MyNullable<Double> NullableDoubleTest;
NullableDoubleTest.Value = 63.0;
// Also compiles fine and works as expected
MyNullable<MyNullable<Double>> NullableNullableTest;
NullableNullableTest.Value.Value = 63.0;
// Fails to compile...despite Nullable being a struct
// Error: The type 'double?' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'ConsoleApplication1.MyNullable<T>'
MyNullable<Nullable<Double>> MyNullableSuperStruct;
}
}
发布于 2012-04-18 02:12:20
它是一个struct
。它只是不满足值类型泛型参数约束。从语言规范的10.1.5开始:
值类型约束指定用于类型参数的类型实参必须是不可为空的值类型。具有值类型约束的所有不可为空的结构类型、枚举类型和类型参数都满足此约束。请注意,尽管分类为值类型,但可空类型(§4.1.10)不满足值类型约束。
所以,where T : struct
并不是你想的那样。
基本上为什么下面的内容在C#中是无效的?
因为只有不可为空值类型的T
才能满足where T : struct
。Nullable<TNonNullableValueType>
不满足此约束。
编译器为什么以及如何阻止它?
为什么?与规格保持一致。多么?通过执行语法和语义分析并确定您提供的泛型类型参数T
不满足泛型类型约束where T : struct
。
我可以通过创建我自己的可空结构类来修复它,但是
不,你的版本不能修复它。它基本上与Nullable<T>
完全相同,不同之处在于编译器不会进行特殊处理,并且会导致编译器的实现不会装箱。
我能找到很多好的用法
真的?比如?请记住,Nullable<T>
的基本思想是拥有一个可以包含T
或表示“缺少值”的存储位置。嵌套这个有什么意义?也就是说,Nullable<Nullable<T>>
的意义何在?它甚至在概念上没有意义。这可能就是为什么它是被禁止的,但我只是在猜测(Eric Lippert在上说这种猜测是正确的)。例如,什么是int??
?它表示缺少值的存储位置,或者是int?
,本身是表示缺少值的存储位置,还是int
?有什么用呢?
发布于 2012-04-18 02:19:10
结构约束不允许空值的原因之一是我们希望能够在泛型方法中使用T?
。如果struct
允许可以为空的值类型,编译器将不得不禁止T?
。
在其他情况下,可空类型在编译器中也必须有特殊处理:
null关键字必须可以隐式转换为可为空的类型;对于值类型,这是不可能的。可以将可为空的值类型与false.
??
运算符一起使用;而非
https://stackoverflow.com/questions/10196570
复制相似问题