首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >不允许设置属性的属性

不允许设置属性的属性
EN

Stack Overflow用户
提问于 2011-06-14 06:40:21
回答 5查看 206关注 0票数 5

我不确定这叫什么,也不知道我在哪里看到了这个,所以我真的不知道要搜索什么。因此,我试图解释我的意思。

假设我有以下类结构,其中在TypeA中使用TypeB

代码语言:javascript
代码运行次数:0
运行
复制
class TypeA
{
    public TypeB B
    { get; set }
}

class TypeB
{
    public int X
    { get; set }
}

现在,当我有一个TypeA实例时,我想要禁止,我可以直接修改TypeB的值,而不需要重新分配。所以基本上我想防止这种情况的发生:

代码语言:javascript
代码运行次数:0
运行
复制
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的值。

我想我以前在一些内置对象中看到过类似的事情,这抛出了一个错误和编译时间。这叫什么,如何在我的自定义类型中实现它?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-06-14 06:55:57

可以从TypeA中的属性getter返回TypeB对象的副本

代码语言:javascript
代码运行次数:0
运行
复制
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;

在这两种情况下,属性的调用方式都是相同的,并且无法知道调用代码对结果做了什么……

票数 3
EN

Stack Overflow用户

发布于 2011-06-14 06:50:49

在WPF/Silverlight中,有两个“密封”和“冻结”对象的概念。基本上,一旦封存/冻结,对象就不能更改。您可以在这里应用相同的逻辑:

代码语言:javascript
代码运行次数:0
运行
复制
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,如下所示:

代码语言:javascript
代码运行次数:0
运行
复制
class TypeB : SealableObject
{
    private int x;
    public int X
    {
        get { return this.x; }
        set {
            this.VerifyNotSealed();
            this.x = value;
        }
}

然后,当TypeB被分配给您的TypeA属性时,您需要密封它。

票数 3
EN

Stack Overflow用户

发布于 2011-06-14 06:55:49

TypeB实现一个仅使用getter定义X的接口。在TypeA上公开具有此接口类型的属性。现在,您只能在进行向下转换时修改属性的属性,这是您最多只能达到的目标。

此方法将为您提供编译时安全性。如果你只需要运行时安全,看看CodeNaked的答案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6337247

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档