[英]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.