http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx
在上面提到的文章中我读过。 " 每个值类型都有一个隐式默认构造函数,用于初始化该类型的默认值。"
但在本文中,Jon Skeet说
Why can't I define a default constructor for a struct in .NET?
" C#中的基本规则是"任何类型的默认值都不能依赖于任何初始化" 意思是评论中提到的。 默认值始终是"您通过擦除内存"获得的内容。您无法提供任何始终被调用的显式实现。
有人能告诉我谁是正确的吗?
当声明值类型时,实际发生的事情是调用其构造函数或擦除内存。
答案 0 :(得分:3)
当声明其构造函数的值类型时实际发生的事情 被叫或记忆被消灭了。
假设您有以下内容:
public struct Foo
{
public int A { get; set; }
public object B { get; set; }
}
并分配Foo
:
var f = new Foo();
编译器发出对initobj
的调用:
IL_0001: ldloca.s 00 // f
IL_0003: initobj UserQuery.Foo
将指定地址的值类型的每个字段初始化为a null引用或适当原始类型的0
继续描述 如何初始化:
initobj指令初始化值类型的每个字段 由推送的地址(类型为native int,&或*)指定为a null引用或0 的相应基元类型。在这之后 调用方法,实例已准备好构造函数方法 调用。如果typeTok是引用类型,则此指令具有相同的名称 效果为ldnull,后跟stind.ref。与Newobj不同,initobj确实如此 不要调用构造函数方法。 Initobj用于初始化 值类型,而newobj用于分配和初始化对象。
所有这些实际上都证明了值类型做被初始化的事实(因为看起来您可能会质疑该陈述)。
请注意,从 C#6.0 开始,您可以为值类型声明默认的无参数构造函数。如果这样做,如果您通过new
运算符显式实例化您的值类型,则会调用它。
表达式'new Person()'将执行声明的构造函数 而不是提供默认值的标准行为。注意, 但是,'default(Person)'仍会产生默认值, 和每个数组元素的'new Person [...]'一样。在那些情况下 构造函数未执行:仅在您明确使用时才执行 结构类型的'new'。
对于所有托管CLR类型(垃圾收集器),擦除它的人都是一样的。它会注意到它不再被指向,并将收集类型并发挥其魔力。
答案 1 :(得分:2)
两个链接都不相互矛盾。如果你能解释为什么这么认为会有所帮助。
您似乎认为"任何类型的默认值都不能依赖于任何初始化" 意味着"值类型不是" t初始化" ,这不是真的。 They get initialized to 0。
Jon的意思是说(并且确实如此)"用户无法为价值类型提供自定义构造函数" 。
答案 2 :(得分:0)
这根本不是什么神秘的事。使用隐式默认构造函数初始化所有值类型,该构造函数负责为类型分配默认值。实际上,这是一个显示每种值类型的默认值的链接。