代码之家  ›  专栏  ›  技术社区  ›  Robert H.

私有成员实例化/初始化的最佳实践是什么?[复制品]

  •  1
  • Robert H.  · 技术社区  · 17 年前

    可能重复:
    C# member variable initialization; best practice?

    这有什么好处吗?

    public class RemotingEngine
    {
        uint m_currentValueId;
        object m_lock;
    
        public RemotingEngine()
        {
            m_currentValueId = 0;
            m_lock = new object();
        }
    

    与此有关:

    public class RemotingEngine
    {
        uint m_currentValueId = 0;
        object m_lock = new object();
    

    我一直在避开第二个,只是因为它感觉“脏”。很明显,打字少了,所以这对我很有吸引力。

    8 回复  |  直到 17 年前
        1
  •  7
  •   Joel Coehoorn    17 年前

    它可以在继承情况下产生差异。请参见对象初始化顺序上的此链接:
    http://www.csharp411.com/c-object-initialization/

    1. 派生静态字段
    2. 派生静态构造函数
    3. 派生实例字段
    4. 基本静态字段
    5. 基本静态构造函数
    6. 基本实例字段
    7. 基实例构造函数
    8. 派生实例构造函数

    因此,如果这是一个派生类,那么在初始化派生字段和运行构造函数之间初始化整个基对象。

        2
  •  1
  •   Malfist    17 年前

    没有太大的区别,我会和第一个保持一致,因为它更可读。通常变量是在类的顶部定义的,我可以去那里检查它们的默认值,而不是搜索一个构造函数并查看它是否设置了它。就编译器而言,没有区别,除非您有多个构造函数。

        3
  •  1
  •   Artel    17 年前

    出于这个原因,我总是使用第一个:构造函数负责初始化变量。不同的构造函数可以不同地初始化变量。所以,是的,你应该觉得第二种方式是肮脏的。

        4
  •  1
  •   Robert Kozak    17 年前

    我更喜欢第二种,在某些情况下,这取决于您的编码标准。但考虑处理顺序:

    目标类字段初始化->基类字段初始化->基类构造函数->目标类构造函数

    如果基类或目标类在创建对象时出现异常,并且字段已预初始化,则在完成时它将具有值,并且可能导致一些意外问题。

    另见比尔·西姆瑟的博客 Best Practices and Member Initialization in C#

        5
  •  0
  •   Steven Evers    17 年前

    对于int,根本不需要这样做,内部类型初始化为default()——对于int,它是0。

    至于对象,我觉得这是个品味问题,我更喜欢前者。如果有人正在重写我的构造函数,我希望他们调用base()以正确的状态构造它。

        6
  •  0
  •   Brandon Grossutti    17 年前

    您希望避免在构造函数的范围之外进行实例化,因为它显示了意图,特别是如果您要重写构造函数,那么您就有了更多的灵活性。

        7
  •  0
  •   Andrew Hare    17 年前

    就白细胞介素而言,它们是相同的。

    编译器将此转换为:

    class Foo
    {
        int bar = 1;
    }
    

    进入这个:

    class Foo
    {
        int bar;
    
        public Foo()
        {
            this.bar = 1;
        }
    }
    

    即使您自己添加这样的构造函数:

    class Foo
    {
        int bar = 1;
    
        public Foo(int bar)
        {
            this.bar = bar;
        }
    }
    

    编译器将其转换为:

    class Foo
    {
        int bar;
    
        public Foo(int bar)
        {
            this.bar = 1;
            this.bar = bar;
        }
    }
    
        8
  •  0
  •   tvanfosson    17 年前

    我对这个有不同的看法。我认为您应该抽象到属性并在构造函数中设置它们。使用自动属性基本上可以消除这个问题,因为您无法初始化它们(除了默认值之外)。

    public class RemotingEngine {
        private uint CurrentValueID { get; set; }
        private object Lock { get; set; }
    
        public RemotingEngine()
        {
            this.CurrentValueID = 0; // not really necessary...
            this.Lock = new object();
        }
    }
    
    推荐文章