值类型的实例构造函数

来源:互联网 发布:老九门直播软件 编辑:程序博客网 时间:2024/06/03 17:19
关于值类型的实例构造函数有如下的一些规则:
1、值类型不能有无参数的实例构造函数,将发生编译错误,例如下面的代码将发生“Error 1 Structs cannot contain explicit parameterless constructors ”的编译错误。
struct TestStruct
{
int x;
int y;
public TestStruct()
{
x = 10;
y = 20;
}
}
2、值类型可以有含参数的构造函数。且可以用new来调用它。
3、对于引用类型用new构造的时候会发生三件事情(前面文章有述),而对于值类型调用new仅仅是调用构造器来初始化已经分配好的内存的值。根据这一原则,对于值类型的构造有如下两点需要讨论:
1)如果值类型对象作为局部变量,则值类型对象必然要分配在栈上,此时,对于如下两种构造将有如下的区别:
TestStruct testStruct = new TestStruct();
TestStruct testStruct;
根据前面所述原则,两者的区别在于第一种构造为testStruct进行了初始化,而第二种构造方法没有对testStruct对象进行初始化。因此,对于第二种构造下面的代码会产生“Error 1 Use of possibly unassigned field 'x' ”的编译错误,即没进行初始化。
TestStruct testStruct;
int p = testStruct.x;
但是我们如果我们事先对testStruct中的相关字段进行了初始化,程序将顺利运行。例如:
TestStruct testStruct;
testStruct.x = 10;
int p = testStruct.x;
而对于第一种构造方式,由于调用new即完成了初始化,大大提高了编程效率,因此比较广泛的使用。
2)如果值类型对象作为类成员,此时值类型对象将作为引用类型对象的成员分配到栈上,分配到栈上的字段会自动被初始化为0,因此对于下面两种构造方式没有太大的区别。
public class TestClass
{
public TestStruct testStruct = new TestStruct();
public TestStruct testStruct;
}
而且对于下面的代码也能顺利运行:
public class TestClass
{
public TestStruct testStruct;
public TestMethod()
{
int p = testStruct.x; // p = 0
}
}
总结以上所述:1、值类型调用new构造仅仅是为了初始化内存,2、值类型对象作为局部变量和引用类型字段的表现不同,本质原因在于,CLR将自动为在堆上分配的内存初始化,而在栈上分配的内存不自动初始化。3、new是构造值类型对象的通用方法,但不是唯一方法,用这种方法构造可以提高效率,避免一些细小的问题。