【问题标题】:How to keep field readonly?如何保持字段只读?
【发布时间】:2013-06-22 12:27:50
【问题描述】:

假设我们有以下类:

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

但是附加的不再是只读的(因为它没有在 ctor 中初始化)。

如何优雅地解决这个问题?

【问题讨论】:

  • additional 的评估是否依赖于构造函数参数?如果没有,您可以将评估移至另一个私有构造函数并从您的公共构造函数中调用它。
  • ...// 长代码... 在构造函数中评估任何内容本身就是一种代码味道。来自 MSDN:除了捕获构造函数参数之外,构造函数不应该做太多工作。任何其他处理的成本应延迟到需要时。

标签: c# initialization member readonly


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    private C()
    {
        //long code evaluating additional
    }
    
    C(DataType newData)
        : this()
    {
        data = newData;
    }
    

    【讨论】:

      【解决方案3】:

      你可以这样做:

      C(DataType newData)
          :this ()
      {
          data = newData;
      }
      
      C(OtherType newData)
          :this ()
      {
          // eval data from newData
      }
      
      private C()
      {
          EvalAdditional();
      }
      

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

      【讨论】:

      • 问题是如何保留additional字段readonly
      猜你喜欢
      • 2015-12-09
      • 1970-01-01
      • 1970-01-01
      • 2019-06-04
      • 1970-01-01
      • 1970-01-01
      • 2014-01-19
      • 2019-01-29
      • 1970-01-01
      相关资源
      最近更新 更多