如何保持现场只读?

时间:2013-06-22 12:27:50

标签: c# initialization member readonly

我们假设我们有以下课程:

class C
{
    private readonly DataType data;
    private readonly AdditionalType additional;

    C(DataType newData)
    {
        data = newData;
        // LONG code evaluating additional
    }

    C(OtherType newData)
    {
        // eval data from newData
        // the same LONG code evaluating additional
    }
}

dataadditional在C的整个生命周期中都保持不变。但是,有一种代码气味:评估additional的部分在两个构造函数中都加倍了。然后自然选择将其提取到另一种方法:

class C
{
    private readonly DataType data;
    private readonly AdditionalType additional;

    private void EvalAdditional()
    {
        // LONG code evaluating additional
    }

    C(DataType newData)
    {
        data = newData;
        EvalAdditional();
    }

    C(OtherType newData)
    {
        // eval data from newData
        EvalAdditional();
    }
}

但是另外不再是readonly(因为它没有在ctor中初始化)。

如何以优雅的方式解决这个问题?

3 个答案:

答案 0 :(得分:4)

让方法EvalAdditional返回additional对象(而不是void)。

readonly DataType data;
readonly AdditionalType additional;

AdditionalType EvalAdditional()
{
    // LONG code evaluating additional
    return additional;
}

C(DataType newData)
{
    data = newData;
    additional = EvalAdditional();
}

C(OtherType newData)
{
    // eval data from newData
    additional = EvalAdditional();
}

答案 1 :(得分:2)

如果additional的评估不依赖于给予其他构造函数的参数,则可以将其移动到私有构造函数并从公共构造函数中调用它:

private C()
{
    //long code evaluating additional
}

C(DataType newData)
    : this()
{
    data = newData;
}

答案 2 :(得分:0)

你可以这样做:

C(DataType newData)
    :this ()
{
    data = newData;
}

C(OtherType newData)
    :this ()
{
    // eval data from newData
}

private C()
{
    EvalAdditional();
}

虽然这在很大程度上取决于EvalAdditional正在做什么,但如果需要,您可以传递参数。