成員的可訪問性
CLR術語 c#術語 描述 Private private 成員只能由定義類型或任何鑲嵌類型中的方法訪問 Family protected 成員只能由定義類型、任何鑲嵌類型或不管在什麼程序集中的一個派生類型中的方法訪問 Family and Assembly (不支持) 成員只能由定義類型、任何鑲嵌類型或同一程序集中定義的任何派生類型中的方法訪問 Assembly internal 成員只能由定義程序集中的方法訪問 Family or Assembly protected internal 成員可由任何嵌套類型、任何派生類型(不管什麼程序集)或者定義程序集中的任何方法訪問 Public public 成員可由任何程序集的任何方法訪問如果沒有顯示聲明成員的可訪問性,編譯器通常默認選擇private。CRL要求接口類型的所有成員都具有public可訪問性。
一個派生類重寫在他的基類型中定義的一個成員時,c#編譯器要求原始成員和重寫成員具有相同的可訪問性。(CRL不需要)
任何成員想要被別人訪問到,都必須在一個可見的類型內定義。如果程序集A定義了一個internal類型,該類型有一個public方法,那麼程序集B就不能訪問這個public方法。
友元程序集
友元程序集適用於定義類型是internal的類型能訪問另一個定義類型也是internal的類型。
構建程序集時可以使用在system。Runtime.CompilerService命名空間中定義的一個名為InternalsVisibleTo的attribute來標明他認為是“友元”的其他程序集。這個attribute要獲取一個字符串參數,這個字符串
標識了友元程序集的名稱和公鑰。一個程序集在確認了自己的友元程序集之後,那些友元程序集就能訪問該程序集中所有internal類型,以及這些類型的internal成員。
下例展示了一個程序集如何將兩個強命名程序集“Wintellect”和“Microsoft‘指定為他的友元程序集
using System
using System.Runtime.CompilerServices;//為了IntrenalVisibleTo attribute //當前程序集中的internal類型可由以下兩個程序集中的任何代碼訪問(不管什麼版本或什麼語言文化) [assembly: InternalsVisibleTo("Wintellect, PublicKey=1111")] [assembly: InternalsVisibleTo("Microsoft, PublicKey=2222")] internal sealed class SomeInternalType { } internal sealed class AnotherInternalType { }
//以下為公鑰為2222的友元程序集”Wintellect“如何訪問上述程序集的internal類型的SomeInternalType
using System
internal sealed class Foo { private static Object SomeMethod() { //這個“Wintellect”程序集能訪問另一個程序集的internal類型,就好像那是一個public一樣 SomeInternalType sit = new SomeInternalType(); return sit; } }
靜態類
有一些永遠不需要實例化的類,例如Console,Math,Environment,ThreadPool類,這些類只有static成員。事實上這種類的唯一目作用就是將一組相關成員結合到一起,例如
Math類定義了一組執行數學運算的方法。在c#中,要用static定義不可實例化的類(static不能用於結構體)
c#對靜態類做了如下限制
靜態類不許直接從System Object 派生,從其他任何基類派生沒有任何意義。繼承只適用於對象,但是不能創建靜態類的實例。
靜態類不能實現任何接口,因為只有使用類的實例時,才能調用類的接口方法。
靜態類只能定義靜態成員,任何實例成員豆漿導致變異器報錯。
靜態類不能作為字段、方法參數或局部變量使用,因為他們都代表引用了一個實例的變量,而這時不允許的,編譯器檢測到任何這樣的用法都會報錯。