现场初始化初始化、现场

2023-09-02 23:45:29 作者:难以启齿的痛

我只是好奇,是否有字段初始化这两种方法之间的任何diferences?当使用至极吗?

I'm just curious, are there any diferences between this two ways of field initialization ? When to use wich one ?

拳的方式

public class Class1
{
   private SomeClass someclass;

   public Class1()
   {
       someclass = new SomeClass(some arg);
   }
}

第二种方法

public class Class1
{
   private SomeClass someclass = new SomeClass(some arg);

}

在第二个例子中的字段可以是只读

The field in the second example could be readonly.

推荐答案

您不能内联初始化字段时利用关键字。这样做的原因是,其中code被执行的命令:所有意图和目的,code初始化一个领域内联的构造课前运行(即C#编译器将prevent访问关键字)。基本上,这是什么意思是,这将不能编译:

You cannot make use of the this keyword when initializing fields inline. The reason for this is the order in which the code is executed: for all intents and purposes, the code to initialize a field inline is run before the constructor for the class (i.e. the C# compiler will prevent access to the this keyword). Basically what that means is this will not compile:

public class Class1
{
   private SomeClass someclass = new SomeClass(this);

   public Class1()
   {
   }
}

但是,这将:

but this will:

public class Class1
{
   private SomeClass someclass;

   public Class1()
   {
       someclass = new SomeClass(this);
   }
}

这是一个微妙的差异,但有值得我们作出说明。

It's a subtle difference, but one worth making a note of.

这两个版本之间的其他区别使用继承时​​,是唯一真正明显。如果您有相互继承两个类,在派生类中的字段将被首先初始化,然后在基类中的字段将被初始化,然后构造基类将被调用,最后的构造派生类将被调用。有些情况下,你必须要非常小心,因为它可能引起并发症的水果沙拉,如果你不明白是怎么回事(其中一个需要调用基类构造函数在一个虚拟的方法,但几乎从来没有一个明智之举)。下面有一个例子:

The other differences between the two versions are only really noticeable when using inheritance. If you have two classes which inherit from each other, the fields in the derived class will be initialized first, then the fields in the base class will be initialized, then the constructor for the base class will be invoked, and finally, the constructor for the derived class will be invoked. There are some cases where you need to be very careful with this, as it could cause a fruit salad of complications if you don't realise what is going on (one of which involves calling a virtual method inside the base class constructor, but that is almost never a wise move). Heres an example:

class BaseClass
{
	private readonly object objectA = new object(); // Second
	private readonly object objectB;

	public BaseClass()
	{
		this.objectB = new object(); // Third
	}
}

class DerivedClass : BaseClass
{
	private object objectC = new object(); // First
	private object objectD;

	public DerivedClass()
	{
		this.objectD = new object(); // Forth
	}
}

您需要在所有的初始化字段可以看到正确的顺序行设置断点。

You will need to set breakpoints on all of the lines that initialize fields to be able to see the correct sequence.