1

我声明了一个具有多个属性的类

class Soil
{
  public double AnglePhi { get; set; }
  public double AngleDelta { get; set; }
  .
  .
  .
}

现在为了操作它们的集合,我构建了另一个专用类,仅出于这个原因。

class Soils
{
  private const Byte numberOPredefined = 10;   
  private IList<Soil> soils;

  public Soil this[ushort i]
  {
    get { return new Soil() { AngleDelta = soils[i].AngleDelta, ... }; }
    set { if (i > numberOPredefined) soils[i] = value; }
  }
  .
  .
  .
}

这背后的逻辑是在某种程度上保护每个土壤实例的属性免受直接操作。在 getter 中提供一个副本,在 setter 中要求一个“完整”的土壤对象。

从我到目前为止的红色,其他解决方案可能是:
使 Soil 类不可变,
返回一个 ReadOnly List(但随后可以操纵内部的引用类型)
将 Soil 类转换为 struct(简单),
用一些逻辑(方法等)增加 Soil 类)。

我想问一下上述“解决方案”是否有任何价值,或者定义不明确。

这是我认为的典型情况,例如拥有一组引用类型并想要封装它们。在这些情况下,典型的思维框架是什么?

编辑:
好的,阅读答案后,我修改了解决方案

class Soil
{
  private readonly double _AnglePhi;
  public double AnglePhi { get { return _AnglePhi; } }

  private readonly double _AngleDelta;
  public double AngleDelta { get { return _AngleDelta; } }
  .
  .
}

class SoilCollection
{
  private List<Soil> _Soils;
  public IList<Soil> Soils { get { return _Soils.AsReadOnly(); } }
  .
  .
}

我认为 Soil 类需要它内部的逻辑,而不是另一个类。如果我发现任何缺点,我会发布。

4

4 回答 4

2

您可以将 Soil 定义为ValueObject然后它在创建后将是不可变的:

class Soil
{
  public Soil(double anglePhi, double angleDelta)
  {
      AnglePhi = anglePhi;
      AngleDelta = angleDelta;
  }

  public double AnglePhi { get; private set; }
  public double AngleDelta { get; private set; }
}

我认为最好将 Soils 重命名为 SoilCollection。

于 2011-01-21T09:19:48.543 回答
2

如果您希望您的土壤类型具有复制语义,请将其定义为结构。然后,您应该通过将支持字段声明为只读并添加适当的构造函数来使其不可变。

struct Soil
{
  private readonly double anglePhi;
  private readonly double angleDelta;

  public Soil(double phi, double delta) {
    this.anglePhi = phi;
    this.angleDelta = delta; 
  }

  public double AnglePhi { get { return anglePhi; } }
  public double AngleDelta { get { return angleDelta; } }
}

如果您将其保留为类,我将不会使用索引器来检索对象的副本。我宁愿使用一种方法来明确用户正在获取对象的副本。并将其设为只读,就像上面的结构一样,就像类一样。这可能也消除了制作副本的需要。

于 2011-01-21T09:20:35.063 回答
1

没有理由必须在 Soil 类上同时实现 setter 和 getter。您可以选择只实现 get ,这将使土壤对象只读。

您显然必须有一些其他方法来设置内部值 - 可以在构造函数中完成。

例如:

class Soil
{
    private double m_anglePhi;

    public Soil( double anglePhi )
    {
        m_anglePhi = anglePhi;
    }

    public double AnglePhi 
    {
        get { return m_anglePhi; }
    }
}
于 2011-01-21T09:20:14.747 回答
1

我会建议:

1) 使土壤类不可变。

2) 将 Soils 类设为只读集合。如中,从 IList 派生并将 add 等方法声明为 interfact 的显式实现。

于 2011-01-21T09:24:57.197 回答