簡體   English   中英

C#參考文獻; 隱藏會員

[英]C# References; Keeping Members Hidden

想象一下,你有一個如下定義的類。

public class SomeClass
{
     public Manager m { get; protected set; }
     public SpecialData data { get; protected set; }

     //More methods and member code here...
}

我需要我的經理類以某種方式能夠更改SpecialData成員的集合引用。 我可以使用C ++中的雙指針或朋友類來完成此操作,但遺憾的是,該選項在C#中不可用。 如何保持SpecialData不受外部用戶設置,同時仍允許Manager類控制設置? 我可以使用內部關鍵字來做到這一點,但這似乎並不是非常安全或干凈......

任何幫助是極大的贊賞。

如果管理器類是與SomeClass相同的程序集的一部分,那么使internal成員可以使同一程序集中的類可以訪問setter:

public SpecialData data { get; protected internal set; }

這類似於在C ++中使用friend ,除了“friendship”擴展到同一程序集的所有成員。

如果管理器是其他程序包的一部分,則可以在程序集上使用InternalsVisibleTo屬性。 但是,在這種情況下,您應該為擴展友誼的程序集簽名,以避免嘗試從未經授權的代碼訪問setter。

如何在Manager類上創建一個事件 ,比如RequestChangeSpecialData事件。 Manager觸發事件, SomeClass將更改SpecialData實例。

public class SomeClass
{
     private  Manager _m;

     public Manager M 
     { 
        get { return _m} 
        set 
        {
            // register/unregister event on property assignment
            if(_m != null)
                _m.RequestChangeSpecialData -= RequestChangeSpecialData;

            _m = value;

            if(_m != null)
                _m.RequestChangeSpecialData += RequestChangeSpecialData;

        }
     }

     public SpecialData Data { get; private set; }

     private void RequestChangeSpecialData(object sender, ChangeSpecialDataEventArgs e)
     {
        // set the new reference
        Data = e.SpecialData;
     }

}

public class Manager
{
    public void DoSomething()
    {
        // the manager class wants to do something, and wants to change the SpecialData instance.., so it fires the event RequestChangeSpecialData


        SpecialData data = new SpecialData();

        // if the event is bound.
        if(RequestChangeSpecialData != null)
            RequestChangeSpecialData(this, new ChangeSpecialDataEventArgs(data));
    }

    public event EventHandler<ChangeSpecialDataEventArgs> RequestChangeSpecialData;
}

public class ChangeSpecialDataEventArgs : EventArgs
{
    public SpecialData Data {get; private set; }

    public ChangeSpecialDataEventArgs(SpecialData Data)
    {
        Data = data;
    }
}

UNTESTED (寫在記事本中)

現在Manager可以更改SpecialData屬性。 這樣管理器不依賴於SomeClass / interface或assembly。

創建一個繼承SomeClass的類,看起來像這樣:

internal class SomeClassDecorator : SomeClass
{
    public void SetSpecialData(SpecialData value)
    {
        data = value;
    }
}

受保護意味着它可用於類的派生,並且由於SomeClass沒有密封,您可以簡單地從它派生並做任何您需要的事情。 然后,您可以使用此裝飾器而不是SomeClass本身。 此外,您可以根據需要擁有盡可能多的裝飾器,每個裝飾器都處理其特殊的SpecialData

它可能不是您正在尋找的,但此處描述的internal關鍵字可以控制同一程序集中的訪問; 它似乎與C ++中的friend關鍵字類似。

你可以把財產internal 這將使該屬性僅在同一個程序集中可見。 (可選)您可以使用InternalsVisibleToAttribute來允許特定程序集訪問該屬性。

另一種方法是使用interface來隱藏該屬性:

public interface ISomeClass
{
     Manager m { get; }
     SpecialData data { get; set; }
}

public class SomeClass : ISomeClass
{
     public Manager m { get; protected set; }
     SpecialData ISomeClass.data { get; set; }

     //More methods and member code here...
}

這樣, data只能從界面參考中看到。

所以這不起作用:

SomeClass c = new SomeClass();
c.data;

但這樣做:

ISomeClass c = new SomeClass();
c.data;

暫無
暫無

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

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