C#值类型初始化之谜
C# Value type Initialization mystery
http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx
在上面提到的文章中我读到了。
“每个值类型都有一个隐式默认构造函数来初始化该类型的默认值。”
但在这篇文章中 Jon Skeet 说
Why can't I define a default constructor for a struct in .NET?
"the basic rule in C# is "任何类型的默认值都不能依赖于任何初始化
意味着评论中提到的。
默认值始终为 "what you'd get by wiping memory"。您不能提供任何将始终被调用的显式实现。
谁能告诉我谁是正确的?
当一个值类型被声明它的构造函数被调用或内存被清除时实际发生了什么。
what actually happens when a value type is declared its constructor is
called or memory is wiped out.
假设您有以下条件:
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
Initializes each field of the value type at a specified address to a
null reference or a 0 of the appropriate primitive type
然后继续描述它们是如何初始化的:
The initobj instruction initializes each field of the value type
specified by the pushed address (of type native int, &, or *) to a
null reference or a 0 of the appropriate primitive type. After this
method is called, the instance is ready for a constructor method to be
called. If typeTok is a reference type, this instruction has the same
effect as ldnull followed by stind.ref. Unlike Newobj, initobj does
not call the constructor method. Initobj is intended for initializing
value types, while newobj is used to allocate and initialize objects.
所有这些实际上都说明了值类型 do 被初始化的事实(从你的问题看来你可能会质疑那个陈述)。
请注意,从 C# 6.0 开始,您 可以 为值类型声明一个默认的无参数构造函数。如果这样做,如果您通过 new
运算符显式实例化您的值类型,它将被调用。
The expression ‘new Person()’ will execute the declared constructor
instead of the standard behavior of providing the default value. Note,
however, that ‘default(Person)’ will still produce the default value,
as will ‘new Person[…]’ for each of the array elements. In those cases
the constructor is not executed: It’s only when you explicitly use
‘new’ on the struct type.
对于所有托管的 CLR 类型,垃圾收集器由谁清除。它会注意到它不再被指向,并且会收集类型并发挥它的魔力。
这两个链接并不矛盾。如果您能解释一下您为什么这么认为,将会有所帮助。
你好像认为"the default value for any type can't rely on any initialization"就是"value types don't get initialized",这是不对的。 They get initialized to 0。
乔恩在那里想说的(并且确实说了)是 "Users can't provide a custom constructor for value types"。
真的一点都不神秘。所有值类型都使用隐式默认构造函数进行初始化,该构造函数负责为类型分配默认值。事实上,这里有一个 link 显示每个值类型的默认值。
http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx
在上面提到的文章中我读到了。 “每个值类型都有一个隐式默认构造函数来初始化该类型的默认值。”
但在这篇文章中 Jon Skeet 说
Why can't I define a default constructor for a struct in .NET?
"the basic rule in C# is "任何类型的默认值都不能依赖于任何初始化 意味着评论中提到的。 默认值始终为 "what you'd get by wiping memory"。您不能提供任何将始终被调用的显式实现。
谁能告诉我谁是正确的?
当一个值类型被声明它的构造函数被调用或内存被清除时实际发生了什么。
what actually happens when a value type is declared its constructor is called or memory is wiped out.
假设您有以下条件:
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
Initializes each field of the value type at a specified address to a null reference or a 0 of the appropriate primitive type
然后继续描述它们是如何初始化的:
The initobj instruction initializes each field of the value type specified by the pushed address (of type native int, &, or *) to a null reference or a 0 of the appropriate primitive type. After this method is called, the instance is ready for a constructor method to be called. If typeTok is a reference type, this instruction has the same effect as ldnull followed by stind.ref. Unlike Newobj, initobj does not call the constructor method. Initobj is intended for initializing value types, while newobj is used to allocate and initialize objects.
所有这些实际上都说明了值类型 do 被初始化的事实(从你的问题看来你可能会质疑那个陈述)。
请注意,从 C# 6.0 开始,您 可以 为值类型声明一个默认的无参数构造函数。如果这样做,如果您通过 new
运算符显式实例化您的值类型,它将被调用。
The expression ‘new Person()’ will execute the declared constructor instead of the standard behavior of providing the default value. Note, however, that ‘default(Person)’ will still produce the default value, as will ‘new Person[…]’ for each of the array elements. In those cases the constructor is not executed: It’s only when you explicitly use ‘new’ on the struct type.
对于所有托管的 CLR 类型,垃圾收集器由谁清除。它会注意到它不再被指向,并且会收集类型并发挥它的魔力。
这两个链接并不矛盾。如果您能解释一下您为什么这么认为,将会有所帮助。
你好像认为"the default value for any type can't rely on any initialization"就是"value types don't get initialized",这是不对的。 They get initialized to 0。
乔恩在那里想说的(并且确实说了)是 "Users can't provide a custom constructor for value types"。
真的一点都不神秘。所有值类型都使用隐式默认构造函数进行初始化,该构造函数负责为类型分配默认值。事实上,这里有一个 link 显示每个值类型的默认值。