C# 提供了internal關鍵來,來控制程序集的訪問權限。但如果不提供dll的分發形式,internal的價值就無法體現出來。
在管理類和被管理對象之間,常常需要互相訪問一些屬性,這就破壞了封裝性。因爲這些屬性,並不想被其它方法修改,但又不得不標記爲公開。比如:
public class Tween
{
public float duration;
}
public static class TweenManager
{
private static List<Tween> tweenList = new List<Tween>();
public static void AddTime()
{
foreach (var tween in tweenList)
{
// 修改被管理對象的字段,而這個字段不想被其它對象修改
tween.duration += 10.0f;
}
}
}
如上設計,經常在一個功能的一組類之間出現。除了把duration定義爲internal生成dll,要麼就寫註釋,其它沒有辦法控制duration的訪問權限,僅僅是TweenManager之內。
下面,我發現了一個辦法,稍微有一點繁瑣,但基本可以不使用internal的情況下,稍稍控制一下訪問權限。如下:
public class Tween
{
// 繼承可構造
protected Tween()
{
}
// 繼承可見
protected float duration;
}
public static TweenManager
{
public class TweenVisit : Tween
{
protected TweenVisit() : base() {}
public static TweenVisit Get()
{
return new TweenVisit();
}
// 返回受保護的字段
public float Duration
{
get { return this.duration; }
}
}
// 子類當父類返回
public static Tween GetTween()
{
return TweenVisit.Get();
}
// 內部持有的是TweenVisit對象,可以訪問Tween受保護的字段,但是外界拿到的是Tween,無法訪問protected字段
private static List<TweenVisit> tweenList = new List<TweenVisit>();
}
通過這種方法,TweenVisit可以訪問Tween的protected屬性,但是並不對外公開TweenVisit,僅僅留作TweenManager內部使用,起到了保護的作用。
當然,TweenVisit也可以是private class,這樣外界就不能用TweenVisit類型來強轉Tween獲得訪問權限了。
Tween所有隻希望被TweenManager訪問的字段,都可以用protected標記,在TweenVisit中public給TweenManager使用。