Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 私有成员实例化/初始化的最佳实践是什么?_C#_.net - Fatal编程技术网

C# 私有成员实例化/初始化的最佳实践是什么?

C# 私有成员实例化/初始化的最佳实践是什么?,c#,.net,C#,.net,可能重复: 这有什么好处吗: public class RemotingEngine { uint m_currentValueId; object m_lock; public RemotingEngine() { m_currentValueId = 0; m_lock = new object(); } 与此相比: public class RemotingEngine { uint m_currentV

可能重复:

这有什么好处吗:

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

我一直在回避第二个,只是因为它感觉“脏”。很明显,它的输入量较少,因此对我很有吸引力。

就IL而言,它们是相同的

编译器将此转换为:

class Foo
{
    int bar = 1;
}
为此:

class Foo
{
    int bar;

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

    public Foo(int bar)
    {
        this.bar = 1;
        this.bar = bar;
    }
}
即使您自己像这样添加构造函数:

class Foo
{
    int bar = 1;

    public Foo(int bar)
    {
        this.bar = bar;
    }
}
编译器将其转换为:

class Foo
{
    int bar;

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

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

就IL而言,它们是相同的

编译器将此转换为:

class Foo
{
    int bar = 1;
}
为此:

class Foo
{
    int bar;

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

    public Foo(int bar)
    {
        this.bar = 1;
        this.bar = bar;
    }
}
即使您自己像这样添加构造函数:

class Foo
{
    int bar = 1;

    public Foo(int bar)
    {
        this.bar = bar;
    }
}
编译器将其转换为:

class Foo
{
    int bar;

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

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

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

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

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

我总是用第一种方法,因为初始化变量是构造函数的责任。不同的构造函数可能会以不同的方式初始化变量。所以,是的,用第二种方法做应该会感觉脏兮兮的。

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


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

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


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

您希望避免在构造函数的作用域之外实例化,因为它显示了意图,特别是当您重写构造函数时,您有更大的灵活性

您希望避免在构造函数的作用域之外实例化,因为它显示了意图,尤其是当您是重写构造函数您有更大的灵活性

它可以使继承情况有所不同。请参见对象初始化顺序上的此链接:

  • 导出静态场
  • 派生静态构造函数
  • 派生实例字段
  • 基本静态场
  • 基本静态构造函数
  • 基本实例字段
  • 基本实例构造函数
  • 派生实例构造函数

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

    它可以改变继承情况。请参见对象初始化顺序上的此链接:

  • 导出静态场
  • 派生静态构造函数
  • 派生实例字段
  • 基本静态场
  • 基本静态构造函数
  • 基本实例字段
  • 基本实例构造函数
  • 派生实例构造函数

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

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

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

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


    另请参见Bill Simser的博客

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

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

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


    另请参见比尔·西姆斯的博客

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


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


    直到找到另一个构造函数added@NeilN:请再解释一下——你的说法没有任何意义。在某些情况下(当你推导出来的时候),IL肯定是不一样的。你有具体的例子吗?我看不出拥有派生类型有什么关系。如果在基类构造函数期间发生异常,则派生构造函数将不会运行,但字段初始化器会运行,直到另一个构造函数运行为止added@NeilN:请再解释一下——你的陈述没有任何意义