当一个构造函数实现另一个构造函数时,是否有好处或缺点

Nop*_*ope 18 c# constructor

如果我有这样的课程:

public class Foo
{
    public IEnumerable<Bar> Bars { get; set; }

    public Foo()
    {
        Bars = new List<Bar>();
    }
}
Run Code Online (Sandbox Code Playgroud)

在某个阶段,我重新考虑类并添加一个辅助构造函数,它实现第一个,如下所示:

public class Foo
{
    public IEnumerable<Bar> Bars { get; set; }

    // some more properties were added

    public Foo()
    {
        Bars = new List<Bar>();
    }

    public Foo(string parameter): this()
    {
        .... some code here
    }
}
Run Code Online (Sandbox Code Playgroud)

我也可以写它类似于:

public class Foo
{
    public IEnumerable<Bar> Bars { get; set; }

    // some more properties were added too

    public Foo()
    {
        InitilizeFoo();
    }

    public Foo(string parameter)
    {
        InitilizeFoo();
        .... some code here
    }

    private void InitializeFoo()
    {
        Bars = new List<Bar>();
    }
}
Run Code Online (Sandbox Code Playgroud)

看到这两种方法在这种情况下都有效,使用一种方法有没有好处或缺点?

继承构造函数是否更有效并使代码执行得更快或者是否存在一个我不知道如何使第二个实现更高效的缺点?

Jam*_*are 28

让一个构造函数调用另一个构造函数的一个主要好处是,您可以通过这种方式设置只读字段,不能通过调用非构造函数方法来实现.

例如:

public class Foo
{
    private readonly int myNumber;

    public Foo() : this(42)
    {
    }

    public Foo(int num)
    {
        myNumber = num;
    }
}
Run Code Online (Sandbox Code Playgroud)

性能方面,调用另一个构造函数调用另一个方法的效率可能不高或低,但在我看来,构造函数调用另一个构造函数比调用一个单独的私有方法更具可读性.由构造函数调用.

当然,当有一个单独的方法是有道理的时候,它本身肯定不是"错误的".对于大多数用途,链接构造函数只会读取更多,并且没有负面的性能影响.

更新:我执行了10,000,000次单向迭代(链式与私有初始化方法),结果如此接近,几乎无法区分:

Initializer Method took: 84 ms for 10,000,000 iterations, 8.4E-06 ms/each.
Chained Constructors took: 81 ms for 10,000,000 iterations, 8.1E-06 ms/each.
Run Code Online (Sandbox Code Playgroud)

所以真的,在性能方面,无论如何都几乎没有任何好处.主要的好处是使用链式构造函数可以设置readonly字段,并且在大多数情况下它更具可读性.

  • 随时!与任何事情一样,编写一个小测试并使用System.Diagnostics.Stopwatch()来测量每个测试的几百万次迭代真的很容易...... (2认同)
  • @FrançoisWahl:我对每个进行了快速的性能测试,结果每次运行几毫秒都有所不同,但总的来说它们每次都几乎相同...见上面的更新. (2认同)

Rex*_*x M 6

链接构造函数是强制执行SRP和程序流的好方法.Initialize()如果在对象生命周期中还有其他情况你可能也想要"初始化"它,那么在独立函数中隐藏初始化代码是有意义的.也许如果你想能够快速实例化和懒惰初始化它.但是,如果生命周期中执行该功能的唯一有效时间是在实例化期间,并且初始化是一组明确定义的需要按顺序执行的离散步骤,那么链接可以促进这一点.