我想知道什么是第一次被召唤 让我说我有这个代码
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;
订单怎么样?什么需要礼物?
答案 0 :(得分:6)
您的陈述:
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)
编译器通过首先访问对象来处理对象初始化器 默认实例构造函数,然后处理该成员 初始化。因此,如果默认构造函数声明为 在类中私有,需要公共访问的对象初始值设定项 会失败。
答案 1 :(得分:3)
MyNumber br 6或8是什么?
它将是8.当执行以下行时:
var o = new MyObject {MyNumber = 8 };
将创建类型为MyObject
的对象,然后将MyNumber
的值设置为8.在引擎盖下,默认构造函数将用于创建对象。因此,在将MyNumber
设置为8之前,它将为6。
和我刚刚添加的7的故事是什么?
与上述情况相同。现在,您将遇到自动属性初始化程序(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代码!
答案 2 :(得分:-1)
在将新对象分配给类或结构字段时,另一个答案未涵盖的一个用例:
public class MyClass
{
private MyObject m;
public void MyMethod()
{
this.m = new MyObject { MyNumber = 8 };
}
}
因为该字段可能在类之外使用,并且该语句对用户来说是原子的,所以编译器会生成一个临时变量,并且只在完全初始化时为该字段赋值:
var temp = new MyObject();
temp.MyNumber = 8;
this.m = temp;