繁体   English   中英

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

[英]How can I share constructor code with readonly class members?

我有一个FooBarSet类,带有一个单独的“核心”初始化逻辑块。

FooBarFooBar FooBarSetFooBar的列表初始化。 FooBarSet 可以通过单独的并行FooBar列表进行初始化。

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

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

这是C#,不是Java,因此, 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必须为readonly ,我如何才能让这些构造函数共享初始化代码?

您可以将“ 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;
    }
}

简单的答案是让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);
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2025 STACKOOM.COM