可能重复:
Initialize class fields in constructor or at declaration?
我们正在争论编码实践。这里的例子有点过于简单,但真正的交易有几个构造函数。为了初始化简单值(例如日期到它们的最小值),我已经将代码移出构造函数并进入字段定义。
public class ConstructorExample
{
string _string = "John";
}
public class ConstructorExample2
{
string _string;
public ConstructorExample2()
{
_string = "John";
}
}
这本书怎么做?我倾向于非常具体,所以对这种事情可能有点松懈。但是我觉得occams razor告诉我将初始化移出多个构造函数。当然,我总是可以将这个共享初始化转移到私有方法中。
问题本质上是...正在初始化定义它们的字段而不是构造函数以任何方式坏了吗?
我所面对的论点是错误处理之一,但我觉得它不相关,因为没有可能的异常在编译时不会被接收。
答案 0 :(得分:17)
请注意,对于每个构造函数链,所有此类字段声明级初始化都将执行一次,即使构造函数本身将字段设置为其他内容。
如果将构造函数链接在一起,则会在调用的common,first构造函数中初始化字段。
看看这个例子:
using System;
namespace ClassLibrary3
{
public class Class1
{
private string _Name = "Lasse";
public Class1()
{
}
public Class1(int i)
: this()
{
}
public Class1(bool b)
{
_Name = "Test";
}
}
}
此代码编译如下:
using System;
namespace ClassLibrary3
{
public class Class1
{
private string _Name;
public Class1()
{
_Name = "Lasse"
}
public Class1(int i)
: this()
{
// not here, as this() takes care of it
}
public Class1(bool b)
{
_Name = "Lasse"
_Name = "Test";
}
}
}
答案 1 :(得分:13)
初始化构造函数之外的值并不一定是坏的,这里有你遇到的问题:
string _string;
public ConstructorExample2()
{
_string = "John";
}
如果你有多个构造函数,你必须记住要么
1.在每个构造函数中重新初始化_string
2.将逻辑分离为一个通用方法,并在每个构造函数中调用该方法
3.使用其他构造函数中的逻辑调用构造函数。 (链接构造函数)
现在这不一定是个问题,但你必须记住这样做。通过在构造函数之外初始化它,它就完成了。这是你需要记住的事情。
答案 2 :(得分:2)
Microsoft FxCop默认使用构造函数推荐字段初始值设定项。 This question也是这个的副本,应该提供一些见解。
对于静态类,您必须注意this question处理的一些细微之处。
答案 3 :(得分:1)
在上面的示例中,将“John”赋值给_string并不依赖于任何变量,因此它应该在字段初始值设定项的构造函数之外。
只要无法在不可用的状态下初始化对象,那么无关紧要。
编译代码时,无论如何两种方法都是相同的。
答案 4 :(得分:1)
不确定C#,但在Java源代码中,他们似乎更喜欢构造函数,例如:
public class String{
char[] value;
int offset;
...
public String(){
value = new char[0];
offset = 0;
...
}
}
答案 5 :(得分:1)
我认为对于简单的初始化,就像在声明中做到这一点一样好。但是,我不理解错误处理参数。即使初始化中存在异常,我认为您会发现正常的错误处理机制将起作用。当你调用构造函数时,它仍会抛出异常。
答案 6 :(得分:1)
我倾向于初始化get访问器中的东西,它们首先被使用。如果为null则初始化所有。
答案 7 :(得分:0)
我更喜欢在构造函数之外初始化简单字段。
它不应该引起任何问题,因为编译实际上会在编译时将这些初始化移动到构造函数中。
答案 8 :(得分:0)
如果变量的初始化是相同的,无论将哪些参数传递给构造函数,那么使用不必要的初始化代码使构造函数方法混乱是没有意义的。在这种情况下,我就地初始化。
答案 9 :(得分:0)
对构造函数中的字段进行Inisialing会更好。这样,如果/当添加了不同的构造函数时,您知道所有字段都以null / default值开头,您可以适当地初始化它们。