Skip to main content
 首页 » 编程设计

c#之在集合中封装引用类型

2024年01月29日27fff_TT

我声明了一个有几个属性的类

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

这背后的逻辑是在一定程度上防止对每个 Soil 实例的属性进行直接操作。在 getter 中提供一个副本,在 setter 中请求一个“完整的”土壤对象。

到目前为止,根据我的红色,其他解决方案可能是:
使 Soil 类不可变,
返回一个 ReadOnly 列表(但可以操作内部的引用类型)
将 Soil 类转为结构体(简单),
用一些逻辑(方法等)扩充 Soil 类。

我想问一下上面的“解决方案”是否有任何值(value),或者定义不明确。

这是我认为的典型情况,例如,有一个引用类型的集合并希望将它们封装起来。在这些情况下,典型的思维框架是什么?

编辑:
好的,看完答案后我修改了这个解决方案

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 类需要在其中包含逻辑,而不是在另一个 类中。如果我发现任何不足,我会发布。

请您参考如下方法:

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

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

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