我不确定这叫什么,也不知道我在哪里看到了这个,所以我真的不知道要搜索什么。因此,我试图解释我的意思。
假设我有以下类结构,其中在TypeA
中使用TypeB
class TypeA
{
public TypeB B
{ get; set }
}
class TypeB
{
public int X
{ get; set }
}
现在,当我有一个TypeA实例时,我想要禁止,我可以直接修改TypeB的值,而不需要重新分配。所以基本上我想防止这种情况的发生:
TypeA a = new TypeA();
// this should not be possible:
a.B.X = 1234;
// but this should work:
TypeB b = a.B;
b.X = 1234;
a.B = b;
原因是我以一种特殊的方式持久化对象,所以为了正确跟踪TypeB
中的更改,我想要求重新分配TypeA
中的B
的值。
我想我以前在一些内置对象中看到过类似的事情,这抛出了一个错误和编译时间。这叫什么,如何在我的自定义类型中实现它?
发布于 2011-06-13 22:55:57
可以从TypeA
中的属性getter返回TypeB
对象的副本
class TypeA
{
private TypeB _b;
public TypeB B
{
get { return (TypeB)_b.Clone(); }
set { _b = value; }
}
}
这将阻止直接修改_b的属性。然而,它实际上不会禁止执行a.B.X = 1234;
,但指令将不起作用(它只会修改立即被丢弃的副本)。
除非TypeB
是一个结构,否则没有办法阻止这样的指令:
TypeB b= a.B;b.X = 1234;
和
a.B.X = 1234;
在这两种情况下,属性的调用方式都是相同的,并且无法知道调用代码对结果做了什么……
发布于 2011-06-13 22:50:49
在WPF/Silverlight中,有两个“密封”和“冻结”对象的概念。基本上,一旦封存/冻结,对象就不能更改。您可以在这里应用相同的逻辑:
public class SealableObject {
public bool IsSealed { get; private set; }
public void Seal() {
if (this.IsSealed)
throw new InvalidOperationException("The object is already sealed");
this.IsSealed = true;
}
protected void VerifyNotSealed() {
if (this.IsSealed)
throw new InvalidOperationException("Object is sealed");
}
}
然后,您需要在派生类TypeB
中检查IsSealed
,如下所示:
class TypeB : SealableObject
{
private int x;
public int X
{
get { return this.x; }
set {
this.VerifyNotSealed();
this.x = value;
}
}
然后,当TypeB被分配给您的TypeA属性时,您需要密封它。
发布于 2011-06-13 22:55:49
让TypeB
实现一个仅使用getter定义X
的接口。在TypeA
上公开具有此接口类型的属性。现在,您只能在进行向下转换时修改属性的属性,这是您最多只能达到的目标。
此方法将为您提供编译时安全性。如果你只需要运行时安全,看看CodeNaked的答案。
https://stackoverflow.com/questions/6337247
复制相似问题