我不断来回弹跳,并想标准化最好的一个:
private MyOtherClass mc = new MyOtherClass(); // up here OK?
public MyClass()
{
// or down here?, mc = new MyOtherClass();
}
声明时的初始化发生在什么时候?程序第一次启动是什么时候?
我不断来回弹跳,并想标准化最好的一个:
private MyOtherClass mc = new MyOtherClass(); // up here OK?
public MyClass()
{
// or down here?, mc = new MyOtherClass();
}
声明时的初始化发生在什么时候?程序第一次启动是什么时候?
真正的区别很小。它们都编译成几乎相同的东西。主要取决于您的编码风格。您应该知道在调用超级构造函数之前已初始化字段,但依赖这一事实将是不好的做法。
我更喜欢在构造函数中初始化我的所有字段,这样我就可以更好地控制它们的初始化顺序。
两者都可以:这实际上是一个偏好问题,或者您希望如何组织构造逻辑。
请注意,在构造函数运行之前,首先设置内联值。即,以下输出bar
:
public class MyClass
{
private string _member = "foo";
public string Member { get { return _member; } }
public MyClass()
{
_member = "bar";
}
}
class Program
{
static void Main(string[] args)
{
var myClass = new MyClass();
Console.WriteLine(myClass.Member);
Console.ReadLine();
}
}
在您的帖子中,您问“声明时的初始化是什么时候发生的?程序第一次启动的时候?”。
其他答案是正确的,但我只是想强调一点:
private MyOtherClass mc = new MyOtherClass();
是声明一个实例字段,并在实例实例化时初始化,而不是在程序启动时初始化。
如果您声明了一个静态字段:
private static MyOtherClass mc = new MyOtherClass();
这将在类型构造函数运行时初始化,这发生在第一次访问类的任何成员时(模一些复杂性,Jon Skeet 和 Eric Lippert 会比我更好地解释)。
在这两种情况下,程序启动时都不会初始化该字段。
我会这样说:如果这只是一个独立的类,那么在哪里初始化都没有关系。什么时候这个类将成为基类,那时可能很重要。具体来说,我说的是执行顺序。如果你想要你的基础初始化,那么将初始化移动到构造函数。根据构造函数的声明方式等,执行链可能有不同的变体,所以答案是,这可能是重要的,也可能是无关紧要的。如果密封类绝对没关系。但是一旦涉及到继承,答案就不稳定了。
两种方式都可以。对我来说,我提出了以下规则:
如果一个属性总是以相同的方式初始化,无论使用哪个构造函数,我都会在声明时初始化它,所以我只有一次。使构造函数保持一点清洁。
如果根据选择的构造函数有不同的方法来初始化它,我会在构造函数主体中初始化。
public class SomeClass
{
private List<String> content = new List<String>();
private String searchKey;
public SomeClass()
{
searchKey = String.Empty;
}
public SomeClass(String searchKey)
{
this.seachKey = searchKey;
}
// some more code
}
最后回答你关于时间点的问题,当事情开始时:
构造类的第一个实例时,将初始化静态字段。
在构造此类的实例时,所有非静态字段都将被初始化,从在其声明中具有值的字段开始,然后执行构造函数主体以初始化其余部分。