最近我阅读了Nullable文档,发现Nullable的定义如下:
public struct Nullable<T> where T : struct, new()
我曾经误解认为结构体总是有一个公共的无参构造函数,如果这是正确的,那么new()类型约束在这里起到了什么作用?
对于结构体,使用new没有意义。但对于类来说则有意义。
在您的情况下,这是多余的。
public T FactoryCreateInstance<T>() where T : new()
{
return new T();
}
在上述情况下,指定新的约束是有意义的,但当它已经被限制为结构时,则无需进一步指定。
对于值类型来说,无参构造函数是C#的限制而不是CLI的限制。也许这就是为什么会重复指定以留出一些余地。
只是注意到这是有效的、可验证的IL(即。
.class public sequential ansi sealed StructNewStruct`1<valuetype .ctor ([mscorlib]System.ValueType) T>
extends [mscorlib]System.ValueType
编译,就像更简单的一样
.class public sequential ansi sealed StructNewStruct`1<valuetype .ctor T>
extends [mscorlib]System.ValueType
)但我还没有针对这些内容编写任何不同的代码,只是使用简单的where T:struct
(或VB.NET中的(Of T As Structure)
和IL中的<valuetype T>
)提供。
具体来说,对于任何带有简单struct
约束的泛型参数,已经不允许使用Nullable
结构体。(除了存储之外,它似乎对于几乎所有目的都是类。)
因此,总之,Nullable<T>
的当前(等效于)where T:ValueType, struct, new()
似乎当前与where T:struct
完全相同。
提供信息,我使用了更新的DotLisp来创建通用类型(只需使用MakeGenericType
),尝试为4.0框架中所有程序集中的所有类型创建StructNewStruct<t>
和StructStruct<t>
(*)类型,而无需尝试加载“不寻常”的程序集(例如可能未加载System.Web
)。 (如果在“晦涩”的框架程序集中有任何“特殊”类型,请告诉我,我将确保它们被加载并尝试。)所有类型都使用相同的结构成功或失败。
(*) StructStruct<T> where T:struct
null
隐式转换为任何非可空值类型 T
的默认值 Nullable<T>
外,可空类型(令人烦恼的是)不满足结构约束。请注意,将非 null 类型存储位置强制转换为接口类型只会重新解释对现有对象的引用,但每次将非 null 的 Nullable<T>
强制转换为接口类型都会产生一个新的堆类型对象,该堆类型对应于 T
。 - supercatNullable<s>
的类似性,因为它不满足 struct
约束条件。请注意,Nullable<>
本身没有实现 任何 接口,因此总是需要进行转换。 - Mark Hurdnew
约束和struct
约束,但如果将struct
约束应用于间接具有new
约束的类型(通过被限制为具有该约束的泛型类型),则编译器不会报错。我认为结构体能够满足对具有new
约束的泛型类型的约束的唯一方法是将结构体限制为自身(尽管经过再次思考,我并不100%确定,因为... - supercat它不必具有无参数的构造函数,即使它确实拥有一个,也不必是公共的。 我相信“new()”要求它具备这两个条件。
编辑:根据MSDN文档:“new约束指定泛型类声明中的任何类型参数必须具有公共的无参数构造函数。”
ClassType[100]
不会创建任何实例,但创建一个StructType[100]
会创建100个新的结构体实例。 - supercatClassType [100]
实际上为100个指向ClassType
的指针分配内存,而数组StructType [100]
将为100个StructType
分配内存。您所说的是正确的,因为为结构体分配内存等同于创建结构体。 - Rich O'Kellydefault<T>
成为既不是null
也不是new T()
会令人困惑。我不知道CLS规范是否要求语言提供一种显式调用外部定义的结构体的无参数构造函数的方法,因为CIL中没有任何东西可以阻止结构体具有非平凡的无参数构造函数。 - supercat
Nullable<T>
实际上具有约束where T : struct, ValueType, new()
,尽管这种额外的冗余似乎目前并没有增加任何东西。(即 IL 为Nullable`1<valuetype .ctor (System.ValueType) T>
) - Mark Hurd