将引用类型封装在集合中
我声明了一个具有多个属性的类
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您希望 Soil 类型具有复制语义,请将其定义为结构体。然后,您应该通过将支持字段声明为只读并添加适当的构造函数来使其不可变。
如果将其保留为类,我不会使用索引器来检索对象的副本。我宁愿使用一种方法来明确用户正在获取对象的副本。并使其只读,就像上面的结构体一样,就像类一样。这可能也消除了复印的需要。
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.
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.
您可以将 Soil 定义为 ValueObject 那么它在创建后将是不可变的:
我认为最好将 Soils 重命名为 SoilCollection。
You can define Soil as ValueObject then it will be immutable after creation:
And it's better to rename Soils to SoilCollection I think.
没有理由必须在 Soil 类上同时实现 setter 和 getter。您可以选择仅实现 get ,这将使 Soil 对象只读。
显然,您必须有一些其他方法来设置内部值 - 可以在构造函数中完成吗?
例如:
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:
我建议:
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.