私人会员实例化/初始化的最佳实践是什么?

时间:2009-05-28 20:41:44

标签: c# .net

  

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

这有什么好处:

public class RemotingEngine
{
    uint m_currentValueId;
    object m_lock;

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

VS。这样:

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

我一直在避开第二个因为感觉“脏”。这显然不那么打字,所以这对我很有吸引力。

8 个答案:

答案 0 :(得分:7)

它可以改变继承情况。请参阅对象初始化顺序的此链接:
http://www.csharp411.com/c-object-initialization/

  1. 派生的静态字段
  2. 派生的静态构造函数
  3. 派生的实例字段
  4. 基础静态字段
  5. 基础静态构造函数
  6. 基本实例字段
  7. 基本实例构造函数
  8. 派生实例构造函数
  9. 因此,如果这是派生类,则在初始化派生字段和构造函数运行之间初始化整个基础对象。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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

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

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

请参阅Bill Simser Best Practices and Member Initialization in C#

撰写的此博客

答案 4 :(得分:0)

就IL而言,它们是相同的。

编译器将其转为:

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;
    }
}

答案 5 :(得分:0)

对于int,你根本不必这样做,内在类型被初始化为default() - 对于int是0。

至于对象,这是品味的问题。我更喜欢前者。如果有人覆盖了我的构造函数,我希望它们调用base()来构造它在适当的状态。

答案 6 :(得分:0)

你希望避免在构造函数范围之外的实例化,因为它显示了intent,特别是如果你重写构造函数,你会有更多的灵活性

答案 7 :(得分:0)

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

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();
    }
}