二十:构造器之二:实例构造器和结构(值类型)
值类型不像引用类型那样,必须要有构造器,所以编译器不会为值类型生成无参构造器。如下代码:
internal struct Point
{
public Int32 x, y;
}
internal sealed class RefType
{
public Point left, right;
}
为了构建引用类型RefType的实例,必须使用new操作符,并且必须指定一个操作符,在为RefType分配内存时,内存中包含的值类型的两个字段left和right,出于性能方面的考虑,CLR不打算为包含在引用类型内部的每个值类型字段都调用构造器,但CLR会确保值类型的所有字段都会被初始化为0或者null。
CLR也允许在值类型上定义构造器,但是执行必须显示的调用这些构造器,如下所示:
internal struct Point
{
public Int32 x, y;
public Point(Int32 x, Int32 y)
{
this.x = x;
this.y = y;
}
}
internal sealed class RefType
{
public Point left, right;
public RefType()
{
left = new Point(1,2);
right = new Point(100, 200);
}
}
如果RefType的构造器没有使用new操作符来调用Point的构造器来初始化RefType的left和right字段,那么这两个字段中的x和y字段都将为0。再看下面代码:
internal struct Point
{
public Int32 x, y;
public Point()
{
x = y = 10;
}
}
internal sealed class RefType
{
public Point left, right;
public RefType()
{
}
}
现在构建RefType类的实例时,left和right中的x和y字段的值是0还是10呢?C#编译器不允许值类型定义无参的构造器,所以编译不通过。
再看以下代码:
internal struct Point
{
public Int32 x=10;
}
编译也不能通过,因为我们不能用这种方式来初始化值类型的字段。
internal struct Point
{
public Int32 x, y;
public Point()
{
x = 10;
}
}
编译也不能通过,因为构造器必须初始化值类型的所有字段。