当我写作
Nullable<Nullable<DateTime>> test = null;
我收到编译错误:
The type 'System.Datetime?' must be a non-nullable value type in order to use it as a paramreter 'T' in the generic type or method 'System.Nullable<T>'
但Nullable<T>它是struct如此,它应该是不可空的.
所以我试着创建这个struct:
public struct Foo<T> where T : struct
{
private T value;
public Foo(T value)
{
this.value = value;
}
public static explicit operator Foo<T>(T? value)
{
return new Foo<T>(value.Value);
}
public static implicit operator T?(Foo<T> value)
{
return new Nullable<T>(value.value);
}
}
Run Code Online (Sandbox Code Playgroud)
现在我写的时候
Nullable<Foo<DateTime>> test1 = null;
Foo<Nullable<DateTime>> test2 = null;
Foo<DateTime> test3 = null;
Run Code Online (Sandbox Code Playgroud)
第一行是好的,但对于第二行和第三行,我得到以下两个编译错误:
The type 'System.DateTime?' must be a non-nullable value type in order to use it as a parameter 'T' in the generic type or method 'MyProject.Foo<T>' (仅限第二行)
和
Cannot convert null to 'MyProject.Foo<System.DateTime?> because it is a non-nullable value type'
Foo<Nullable<DateTime>> test = new Foo<DateTime?>();
Run Code Online (Sandbox Code Playgroud)
如果Nullable<DateTime>是a,则不会发生任何事件struct.
从概念上讲,我可以理解为什么可以Nullable<T>为空,它可以避免有类似的东西,DateTime??????????但我仍然可以List<List<List<List<List<DateTime>>>>>......
那么为什么这个限制以及为什么我不能重现这种行为Foo<T>呢?这个限制是由编译器强制执行的还是Nullable<T>代码中固有的?
我读过这个问题,但它只是说不可能没有任何答案从根本上说明为什么它不可能.
O. *_*per 10
但是Nullable是一个结构,所以它应该是不可为空的.
Nullable<T>确实是一个结构,但文档中所述的通用struct约束的确切含义是:
type参数必须是值类型.除了
Nullable可以指定的任何值类型.有关更多信息,请参阅使用可空类型(C#编程指南).
出于同样的原因,你的路线
Foo<Nullable<DateTime>> test2 = null;
Run Code Online (Sandbox Code Playgroud)
导致您看到的编译器错误,因为您的泛型struct约束T以某种方式限制您的泛型参数,因此Nullable<DateTime>不能将其指定为实际参数.
对此的理由可能是打电话,如
Nullable<Nullable<DateTime>> test = null;
Run Code Online (Sandbox Code Playgroud)
更加明确:这是否意味着您要设置test.HasValue到false,还是你确实要设置test.HasValue到true和test.Value.HasValue到false?由于对非可空类型参数的给定限制,不会发生这种混淆.
最后,null赋值的工作Nullable<T>原因是 - 正如所选答案及其对这个SO问题和SO问题的评论所暗示的那样- 该Nullable<T>类型由一些编译器魔法支持.