簡體   English   中英

不允許設置屬性的屬性

[英]Disallow setting property's property

我不確定這叫什么,或者我在哪里看到這個,所以我真的不知道要搜索什么。 因此,我試圖解釋我的意思。

假設我有以下 class 結構,其中TypeBTypeA中使用:

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;

原因是我以一種特殊的方式持久化 object,所以為了正確跟蹤TypeB的變化,我想要求重新分配TypeAB的值。

我想我之前在一些內置的 object 中看到過類似的事情,這會引發錯誤和編譯時間。 這叫什么,我怎樣才能在我的自定義類型中實現它?

在 WPF/Silverlight 中有兩個概念,即“密封”和“凍結”對象。 基本上,一旦密封/冷凍,object 就無法更改。 您可以在這里應用相同的邏輯:

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

然后,您需要在派生的 class TypeB中檢查IsSealed ,如下所示:

class TypeB : SealableObject
{
    private int x;
    public int X
    {
        get { return this.x; }
        set {
            this.VerifyNotSealed();
            this.x = value;
        }
}

然后,您需要在將 TypeB 分配給您的 TypeA 屬性時對其進行密封。

您可以從TypeA的屬性獲取器返回TypeB object 的副本:

class TypeA
{
    private TypeB _b;
    public TypeB B
    {
        get { return (TypeB)_b.Clone(); }
        set { _b = value; }
    }
}

這將防止直接修改 _b 的屬性。 但是,它實際上不會禁止執行aBX = 1234; ,但該指令將不起作用(它只會修改將立即丟棄的副本)。

除非TypeB是一個結構,否則沒有辦法阻止這樣的指令:

  • 在編譯時無法檢測到它,因為編譯器不知道它會修改一個副本(同樣,除非它是一個結構)
  • 它也無法在運行時檢測到,因為您無法區分:

     TypeB b = aB; bX = 1234;

    aBX = 1234;

    在這兩種情況下,屬性的調用方式相同,並且無法知道調用代碼對結果做了什么......

TypeB實現一個只用一個 getter 定義X的接口。 TypeA上公開具有此接口類型的屬性。 現在您只能在進行向下轉換時修改屬性的屬性,這是您可以達到的最大目標。

此方法將為您提供編譯時安全性。 如果您只需要運行時安全,請查看 CodeNaked 的答案。

您當前的代碼將不允許您想要什么。 您不能使 int X 讀/寫,並且僅在 B 存儲在 A 中時才使其只讀。如果您真的想保持 int X 不可變,則不要將其保留在 B 類型中。而是將 int 值保留在 A 中, 並將其設為只讀值。

如果您將 class A 中的屬性 B 設為只讀字段怎么辦? 這樣它只能設置一個結構,之后不會改變。

另外,內部/私人二傳手呢? 這能滿足需求嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM