它是更好地初始化在声明类的成员变量
private List<Thing> _things = new List<Thing>();
private int _arb = 99;
或默认的构造函数?
private List<Thing> _things;
private int _arb;
public TheClass()
{
_things = new List<Thing>();
_arb = 99;
}
这纯粹是一个风格问题,还是有性能之间的平衡,一种方式或其他?
在性能方面,有没有真正的区别; 字段初始被实现为构造逻辑。 唯一的区别是之前任何“基地” /“这个”构造函数初始化场发生。
构造函数方法可以自动实现属性可以使用(字段初始不能) - 即
[DefaultValue("")]
public string Foo {get;set;}
public Bar() { // ctor
Foo = "";
}
除此之外,我倾向于选择字段初始值的语法; 我觉得它不断本地化的东西 - 即
private readonly List<SomeClass> items = new List<SomeClass>();
public List<SomeClass> Items {get {return items;}}
我没有去打猎向上和向下要找到它被赋予...
最明显的例外是您需要执行复杂的逻辑或处理构造函数的参数 - 在这种情况下,基于构造函数初始化是要走的路。 同样,如果你有多个构造函数,这将是最好的领域总是设置相同的方式 - 所以你可能有类似构造函数:
public Bar() : this("") {}
public Bar(string foo) {Foo = foo;}
编辑:作为一个方面的评论,请注意,在上面的,如果有其他字段(未显示)字段初始化,那么他们只能直接调用构造函数初始化base(...)
-即public Bar(string foo)
构造函数。 其他的构造函数不运行字段初始,因为它知道他们是由做this(...)
构造函数。
其实,字段初始化为你演示是一个方便的速记。 编译器实际上是拷贝初始化代码到您定义的类型的每个实例构造的开始。
这有两个含义:第一,任何领域的初始化代码在每个构造复制;第二,你在你的构造包括任何代码初始化为特定值的字段将实际上重新分配的领域。
所以性能方面,与关于编译代码的大小,你最好不要动字段初始为构造函数。
在另一方面,对性能的影响和代码“膨胀”通常是可以忽略不计,与外地初始化语法具有减轻你可能忘了初始化你的构造函数中的一个部分领域风险的重要优势。
与现场初始化一个主要限制是,有没有办法将它们包装在一个try-finally块。 如果一个异常是在字段初始抛出,在以前的初始化中分配的所有资源将被放弃; 有没有办法阻止它。 在建设其他错误可以处理,如果笨拙,由具有保护的基础构造参考接受了IDisposable,并在自身指着它作为第一个操作。 然后可以避免调用构造除了通过工厂方法,其在异常的情况下,将调用Dispose部分创建的对象上。 “走私去”的新对象的引用后,这种保护将允许在如果主类的构造失败派生类初始化创建IDisposables的清理。 不幸的是,有没有办法提供这样的保护,如果一个字段初始化失败。
请使用字段初始化或创建一个init()函数。 与把这些东西在你的构造函数的问题是,如果你需要添加第二个构造函数,你结束了复制/粘贴代码(或你忽视它,并与未初始化的变量结束)。
我要么初始化哪里声明。 或具有构造(或多个)调用init()函数。
对于实例变量,它在很大程度上是一个风格问题(我更喜欢使用一个构造函数)。 对于静态变量,有性能优势 ,以初始化内联(并不总是可能的,当然)。
这真的取决于你。
我经常对它们进行初始化内联,因为我不喜欢有一个构造函数时我并不真的需要一个(我喜欢小班!)。
在加点上 - 你实现一个有一个实现类的时候总是有一个构造函数。 如果你没有申报一个,则默认指导员是由编译器推断[公共美孚(){}]。 一个构造函数没有参数。
很多时候,我想提出这两种方法。 允许那些希望使用它们,让字段初始化为您要使用的简化或默认实现你的类/类型的情况下构造。 这增加了灵活性,你的代码。 请记住,任何人都可以使用默认的初始场,如果他们选择......可以肯定的,如果你提供一个以上的构造函数来手动声明它 - 公共美孚(){}