首先叫什么 - 对象初始化器 vs 构造器?
Whats called first - Object Initializer or Construtor?
我想知道先调用什么
假设我有这个代码
public class MyObject
{
public MyObject()
{
MyNumber = 6;
}
public int MyNumber { get; set; }
}
然后我称之为
var o = new MyObject {MyNumber = 8 };
MyNumber
是什么 - 6 还是 8?
假设我也设置了这个
public int MyNumber { get; set; } = 7;
顺序是什么?什么需要礼物?
What will MyNumber br 6 or 8 ?
会是8。当下面一行被执行时:
var o = new MyObject {MyNumber = 8 };
将创建类型为 MyObject
的对象,然后 MyNumber
的值将设置为 8。在幕后,默认构造函数将用于创建对象。所以在 MyNumber
被设置为 8 之前,它将是 6.
and whats the story with the 7 i just added?
同上例。现在,您遇到的是自动 属性 初始化程序(C# 6 中引入的一项功能)。以下
public int MyNumber { get; set; } = 7;
相当于在默认构造函数中初始化MyNumber
的值。
如果您使用以下代码创建控制台应用程序:
public class MyObject
{
public MyObject()
{
MyNumber = 6;
}
public int MyNumber { get; set; }
}
class Program
{
static void Main(string[] args)
{
var o = new MyObject { MyNumber = 8 };
}
}
然后编译代码,用ildasm反编译,如果看Main的IL代码,会得到下图。
从第一条带下划线的行可以清楚地看出调用了默认对象初始化程序。然后在第二个下划线处将 8 的值设置为相应的支持字段。
此外,如果您为以下控制台应用程序编译代码:
public class MyObject
{
public int MyNumber { get; set; } = 8;
}
class Program
{
static void Main(string[] args)
{
var o = new MyObject { MyNumber = 8 };
}
}
您将获得完全相同的 IL 代码!
您的声明:
var o = new MyObject {MyNumber = 8 };
相当于有点
var o = new MyObject();
o.MyNumber = 8;
所以您将得到的结果是 8
,因为分配给 MyNumber
的任何值都将由于对象初始化而被覆盖。
使用 属性 初始值设定项会得到相同的结果,唯一的区别是:
- 在调用构造函数时,属性
MyNumber
将具有默认值 7
- 在构造函数中它会被赋值
6
- 但由于对象初始值设定项,它将被分配
8
在对象初始化器的情况下,首先调用的是构造函数。
How to: Initialize Objects by Using an Object Initializer (C# Programming Guide)
The compiler processes object initializers by first accessing the
default instance constructor and then processing the member
initializations. Therefore, if the default constructor is declared as
private in the class, object initializers that require public access
will fail.
另一个答案未涵盖一个用例,即在将新对象分配给 class 或结构字段时:
public class MyClass
{
private MyObject m;
public void MyMethod()
{
this.m = new MyObject { MyNumber = 8 };
}
}
因为该字段可能在 class 之外使用并且该语句对用户来说看起来是原子的,所以编译器生成一个临时变量并且仅在完全初始化时才为该字段赋值:
var temp = new MyObject();
temp.MyNumber = 8;
this.m = temp;
我想知道先调用什么 假设我有这个代码
public class MyObject
{
public MyObject()
{
MyNumber = 6;
}
public int MyNumber { get; set; }
}
然后我称之为
var o = new MyObject {MyNumber = 8 };
MyNumber
是什么 - 6 还是 8?
假设我也设置了这个
public int MyNumber { get; set; } = 7;
顺序是什么?什么需要礼物?
What will MyNumber br 6 or 8 ?
会是8。当下面一行被执行时:
var o = new MyObject {MyNumber = 8 };
将创建类型为 MyObject
的对象,然后 MyNumber
的值将设置为 8。在幕后,默认构造函数将用于创建对象。所以在 MyNumber
被设置为 8 之前,它将是 6.
and whats the story with the 7 i just added?
同上例。现在,您遇到的是自动 属性 初始化程序(C# 6 中引入的一项功能)。以下
public int MyNumber { get; set; } = 7;
相当于在默认构造函数中初始化MyNumber
的值。
如果您使用以下代码创建控制台应用程序:
public class MyObject
{
public MyObject()
{
MyNumber = 6;
}
public int MyNumber { get; set; }
}
class Program
{
static void Main(string[] args)
{
var o = new MyObject { MyNumber = 8 };
}
}
然后编译代码,用ildasm反编译,如果看Main的IL代码,会得到下图。
从第一条带下划线的行可以清楚地看出调用了默认对象初始化程序。然后在第二个下划线处将 8 的值设置为相应的支持字段。
此外,如果您为以下控制台应用程序编译代码:
public class MyObject
{
public int MyNumber { get; set; } = 8;
}
class Program
{
static void Main(string[] args)
{
var o = new MyObject { MyNumber = 8 };
}
}
您将获得完全相同的 IL 代码!
您的声明:
var o = new MyObject {MyNumber = 8 };
相当于有点
var o = new MyObject();
o.MyNumber = 8;
所以您将得到的结果是 8
,因为分配给 MyNumber
的任何值都将由于对象初始化而被覆盖。
使用 属性 初始值设定项会得到相同的结果,唯一的区别是:
- 在调用构造函数时,属性
MyNumber
将具有默认值7
- 在构造函数中它会被赋值
6
- 但由于对象初始值设定项,它将被分配
8
在对象初始化器的情况下,首先调用的是构造函数。
How to: Initialize Objects by Using an Object Initializer (C# Programming Guide)
The compiler processes object initializers by first accessing the default instance constructor and then processing the member initializations. Therefore, if the default constructor is declared as private in the class, object initializers that require public access will fail.
另一个答案未涵盖一个用例,即在将新对象分配给 class 或结构字段时:
public class MyClass
{
private MyObject m;
public void MyMethod()
{
this.m = new MyObject { MyNumber = 8 };
}
}
因为该字段可能在 class 之外使用并且该语句对用户来说看起来是原子的,所以编译器生成一个临时变量并且仅在完全初始化时才为该字段赋值:
var temp = new MyObject();
temp.MyNumber = 8;
this.m = temp;