初始化显式构造函数之外的字段是不好的做法

时间:2010-05-10 14:40:12

标签: c# constructor initialization

  

可能重复:
  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告诉我将初始化移出多个构造函数。当然,我总是可以将这个共享初始化转移到私有方法中。

问题本质上是...正在初始化定义它们的字段而不是构造函数以任何方式坏了吗?

我所面对的论点是错误处理之一,但我觉得它不相关,因为没有可能的异常在编译时不会被接收。

10 个答案:

答案 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值开头,您可以适当地初始化它们。