将引用类型封装在集合中

发布于 2024-10-12 20:43:09 字数 1313 浏览 1 评论 0原文

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

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 类不可变,
返回一个只读列表(但可以操作内部的引用类型)
将 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 类需要在其中包含逻辑,而不是在另一个类中。如果我发现任何缺点我会发帖。

I declared a class with several properties

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

Now to manipulate a collection of them I built another dedicated class, only for this reason.

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

The logic behind this, is to protect somewhat from direct manipulation of the properties of each Soil instance. Give a copy in getter, ask for a "whole" soil object in setter.

From what I red thus far, other solutions could be:
make Soil class immutable,
return a ReadOnly List (but then the reference types inseide can be manipulated)
turn Soil class to struct (simple),
augment Soil class with some logic (methods etc).

I would like to ask if the above "solution" has any value at all, or is ill-defined.

This is a typical situation I think, eg having a collection of reference types and want to encapsulate them. What is the typical frame of thinking in these situations ?

EDIT :
Ok, after reading the answers I modified the solution to this

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

I think the Soil class needed logic inside it, and not inside another class. I 'll post if I find any shortcomings.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

后eg是否自 2024-10-19 20:43:10

如果您希望 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; } }
}

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

If you want your Soil type to have copy semantics, define it as a struct. You should make it immutable then, by declaring the backing fields as readonly and adding an appropriate constructor.

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

If you keep it as class, I would not use an indexer to retreive copies of the objects. I'd rather use a method to make clear that the user is getting a copy of the object. And make it read-only, just as the struct above, just as class. That would probably also eliminate the need to make copies.

万水千山粽是情ミ 2024-10-19 20:43:10

您可以将 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。

You can define Soil as ValueObject then it will be immutable after creation:

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

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

And it's better to rename Soils to SoilCollection I think.

牵你手 2024-10-19 20:43:10

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

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

例如:

class Soil
{
    private double m_anglePhi;

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

    public double AnglePhi 
    {
        get { return m_anglePhi; }
    }
}

There's no reason you have to implement both the setter and the getter on the Soil class. You can choose only to implement get which would make the Soil objects readonly.

You'd obviously have to have some other method of setting the internal values - could that be done in a constructor.

For example:

class Soil
{
    private double m_anglePhi;

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

    public double AnglePhi 
    {
        get { return m_anglePhi; }
    }
}
很酷不放纵 2024-10-19 20:43:10

我建议:

1)使Soil类不可变。

2) 将 Soils 类设置为只读集合。
如下所示,从 IList 派生并将 add 等方法声明为接口的显式实现。

i would suggest:

1) Make Soil class immutable.

2) Make Soils class a read only collection.
As in, derive from IList and declare the add etc methods as explicit implementaion of interfact.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文