如何与只读类成员共享构造函数代码?

时间:2015-07-21 21:50:38

标签: c# constructor dry

我有一个类line.strip(),其中包含一个“核心”初始化逻辑块。

FooBarSetFooBarFoo组成。使用Bar列表初始化类FooBarSetFooBar也可以 通过单独的并行FooBarSetFoo列表进行初始化。

理想情况下,我可以像这样运行它:

Bar

这是C#,而不是Java,因此public class FooBarSet { private readonly List<FooBar> _list; // Primary constructor. public FooBarSet(List<FooBar> foobarList) { // Contracts and initialization... _list = foobarList; } // Secondary constructor. public FooBarSet(List<Foo> fooList, List<Bar> barList) { // Zip a new list of new FooBars var zipped = fooList.Zip(barList, (foo, bar) => new FooBar(foo, bar)); // Call primary constructor with zipped list. this(zipped); } } 是非法的。常见的解决方案here是将核心初始化拉入一个通用的私有方法:

this(zipped)

但是,由于public class FooBarSet { private readonly List<FooBar> _list; // Common "constructor" called from actual constructors. private Init(List<FooBar> foobarList) { // Contracts and initialization... _list = foobarList; } public FooBarSet(List<FooBar> foobarList) { Init(foobarList); } public FooBarSet(List<Foo> fooList, List<Bar> barList) { var zipped = fooList.Zip(barList, (foo, bar) => new FooBar(foo, bar)); Init(zipped); } } 字段,这也不起作用。

假设readonly _list必须是_list,我该如何让这些构造函数共享初始化代码?

2 个答案:

答案 0 :(得分:3)

您可以将“zipper”代码移动到静态函数并使用:

public class FooBarSet
{
    private readonly List<FooBar> _list;

    private static List<FooBar> Prepare( List<Foo> fooList, List<Bar> barList )
    {
        return fooList.Zip(barList, (foo, bar) => new FooBar(foo, bar));
    }

    public FooBarSet(List<Foo> fooList, List<Bar> barList) :
        this( Prepare( fooList, barList ) )
    {
    }

    public FooBarSet(List<FooBar> zippedList)
    {
        _list = zippedList;
    }
}

答案 1 :(得分:2)

简单的答案是让Init方法返回在构造函数中设置的值:

public class FooBarSet
{
    private readonly List<FooBar> _list;

    // Common "constructor" called from actual constructors.
    private List<FooBar> Init(List<FooBar> foobarList)
    {
        // Contracts and initialization...
        return whateverList;
    }

    public FooBarSet(List<FooBar> foobarList)
    {
        _list = Init(foobarList);
    }

    public FooBarSet(List<Foo> fooList, List<Bar> barList) 
    {
        var zipped = fooList.Zip(barList,
                                 (foo, bar) => new FooBar(foo, bar));

        _list = Init(zipped);
    }

}