以下代码片段有什么区别?
Form1 form1 = new Form1();
和
Form1 form1;
public Class1()
{
form1 = new Form1();
}
在您的具体示例中,没有区别。两者都将编译为相同的 IL。这只是偏好/风格的问题。
一般来说,区别如下:
第一个版本不能访问这个类的其他实例成员,第二个版本可以。
不同之处在于您可以控制在第二种情况下初始化发生的确切时间。
使用内联初始化,您不能依赖一个来初始化另一个:
int a = 42;
int b = a; // not definitely known to have a value yet
当您在构造函数中初始化它们时,您可以控制它们的运行顺序:
int a, b;
public Class1() {
a = 42;
b = a;
}
除此之外,没有任何真正的区别。内联初始化将由编译器放置在构造函数中,因为这是唯一可以进行此类初始化的地方。
在第二个选项中,您声明一个Form1
不包含任何内容(无对象)的类型的引用,直到您使用new
构造函数中的关键字对其进行初始化。在第一个选项中,您立即声明和初始化。
根据C# 特定语言规范 10.11.3:
变量初始化器被转换为赋值语句,并且这些赋值语句在基类实例构造函数的调用之前执行。这种排序确保所有实例字段在执行任何有权访问该实例的语句之前由其变量初始化程序初始化。
在您的具体示例中,没有示例。但是,如果我们在这里运行本规范中的示例:
using System;
class A {
int x = 1;
int y;
public A() {
y = -1;
}
}
当调用 new A() 时,输出 x = 1 和 y = 0(默认值),直到执行构造函数。
第一个片段的结果是 form1 将包含 Form1 类的一个新实例。
第二个片段不会创建一个新实例,只是一个未初始化的变量(它会被初始化为 null)。
结合起来将是:
Form1 form1;
public Class1()
{
form1 = new Form1();
}
现在上面的代码片段是一个类的一部分,当你创建这样一个类的实例时,它会调用 Class1,从而将 form1 分配给 Form1 的一个新实例。例如:
class Class1
{
Form1 form1;
public Class1()
{
form1 = new Form1();
}
}
c = Class1();
c 将调用 Class1 的构造函数,该构造函数调用 new Form1() 并将其分配给 form1。