這段比較短就先干掉了:) 23不完整類型 23.1不完整類型聲明 新類型修飾符partial 用于在多個部分中定義一個類型。為了確保和現存程序的兼容性,這個修飾符和其他修飾符(比如get和set)是不同的,它不是一個關鍵字,并且它必須緊鄰出現在關鍵字class ,struct或者interface之前。
l class-declaration(類聲明) attributes opt class-modifiers opt partialopt class identifier type-parameter-list opt class-base opt type-parameter-constraints-clausesopt class-body ;opt
(特性 可選 類修飾符 可選 partial可選 class 標識符
類型參數列表 可選 :基類 可選 類型參數約束語句 可選 類體;可選)
l struct-declaration:(結構聲明) attributesopt struct-modifiersopt partialopt struct identifier type-parameter-listopt struct-interfacesopt type-parameter-constraints-clausesopt struct-body ;opt
(特性 可選 結構修飾符 可選 partial 可選 struct 標識符
類型參數列表 可選
結構接口 可選 類型參數約束語句 可選
結構體;可選 )
l interface-declaration:(接口聲明) attributesopt interface-modifiersopt partialopt interface identifier type-parameter-listopt interface-baseopt type-parameter-constraints-clausesopt interface-body ;opt
(特性可選 接口修飾符 可選 partial 可選 interface 標識符
類型參數列表 可選
基接口 可選 類型參數約束語句 可選
接口體 ;可選)
不完整類型聲明的每個部分都必須包含partial修飾符,并且和其他部分必須被聲明在相同的命名空間。partial修飾符表明該類型聲明的附加部分可以存在于其他某個地方,但這種附加部分的存在并不是必需的;在一個單一類型聲明中包含partial修飾符也是合理的。
不完整類型的所有部分必須放在一起編譯,這樣它們就可以在編譯時被融合。特別的是,不完整類型不容許對已經被編譯的類型進行擴展。
嵌套類型(nested type)可以通過使用partial修飾符而聲明在多個地方。典型的情況是,包含類型(也就是包含嵌套類型的類型)同樣使用partial聲明,而嵌套類型的各個部分也在包含類型的不同部分中聲明。
partial修飾符不能用在委托或枚舉聲明中。
23.1特性 不完整類型的特性通過以不定的(unspecified)順序組合各個部分的特性而確定。如果一個特性被放在不完整類型的多個部分,它等價于在該類型上多次指定該特性。例如,這兩個部分
[Attr1, Attr2("hello")] partial class A {}
[Attr3, Attr2("goodbye")] partial class A {}
等價于如下聲明。
[Attr1, Attr2("hello"), Attr3, Attr2("goodbye")] class A {}
類型參數上的特性也以相同的風格組合。
23.1.2修飾符 當不完整類型聲明包含訪問說明(public,protected,internal和private)時,它必須與其它部分的訪問說明一致。如果不完整類型的各個部分都不包含訪問說明,該類型將被賦予適當的默認可訪問性(§3.5.1)。
如果嵌套類型的一個或多個不完整聲明包含new修飾符,并且如果嵌套類型隱藏了一個繼承成員,將不會有任何警告。(§3.7.12)
如果類的一個或多個不完整聲明包含abstract修飾符,那么這個類就是抽象的(§10.1.1.1),反之就是非抽象的。
注意,一個類不能同時既是抽象的又是密封的(sealed)。
當unsafe修飾符被用于一個不完整類型聲明時,只有特定的部分被認為是不安全上下[unsafe contex(§18.1))]。
23.1.3類型參數和約束 如果泛型類型在多個部分被聲明,每個部分都必須說明類型參數。每個部分都必須有相同數量的類型參數,并且對于每個類型參數必須有相同的名字和順序。
當不完整泛型聲明包含類型參數約束(where 語句),該約束必須和其他部分的約束一致。特別的是,包含約束的每個部分必須具有相同集合類型參數的約束,并且對于每個類型參數,
類、接口和構造函數約束的集合必須是相同的。如果不完整泛型的任何部分都沒有指定約束,類型參數就被認為是不帶約束的。
示例
partial class Dictionary<K,V> where K: IComparable<K> where V: IKeyProvider<K>, IPersistable { ... }
partial class Dictionary<K,V> where V: IPersistable, IKeyProvider<K> where K: IComparable<K> { ... }
partial class Dictionary<K,V> { ... }
是正確的,因為這些包含約束的部分有效地指定了類、接口的相同集合,以及相應相同集合的類型參數的構造函數約束。
23.1.4基類 當不完整類聲明包含基類說明時,它必須與包含基類說明的所有其他部分一致。如果不完整類聲明的任何部分都不包含基類聲明,那么基類將是System.Object(§10.1.2.1)。
23.1.5基接口 在多個部分中聲明的類型的基接口集合,是在各個部分中指定的基接口的聯合。一個特定的基接口在每個部分中只能被命名一次,但可以在多個部分中命名相同的基接口。但對于任何給出的基接口成員只能有唯一的實現。
在例子
partial class C: IA, IB {...}
partial class C: IC {...}
partial class C: IA, IB {...}
中類C的基接口是IA,IB和IC。
通常,在接口聲明的部分中提供接口的實現;但這不是必需的。一個部分可以為聲明在另一個部分中的接口提供實現。
partial class X { int IComparable.CompareTo(object o) {...} }
partial class X: IComparable { ... }
23.1.6成員 聲明在多個部分中的類型的成員只是在各個部分中聲明的成員的聯合。類型聲明的所有部分的內容共享相同的聲明空間(§3.3),并且每個成員(§3.7)的作用域擴展到所有部分的內容。任何成員的所有可訪問域總是包含封閉類型的所有部分;在一個部分中聲明的private成員可以隨意的在另一個部分訪問。在一個類型的多個部分中聲明相同的成員將造成編譯時錯誤,除非該成員是一個帶有partial修飾符的成員。
partial class A { int x; // 錯誤, 不能多次聲明x
partial class Inner // Ok, Inner 是不完整類型 { int y; } }
partial class A { int x; // 錯誤,不能多次聲明x
partial class Inner // Ok, Inner是不完整類型 { int z; } }
盡管一個類型中成員的次序對于C#代碼并不是太重要,但在面對其他語言和環境時卻可能是很重要的。在這樣的情況下,在多個部分中聲明的類型內成員次序將是未定義的。
23.2名字綁定 雖然可擴展類型的每個部分必須聲明在相同的命名空間,但這些部分也可以寫在不同的命名空間中。為此,對于各個部分可以使用不同的using指令(§9.3)。當在一個部分中解釋簡單名字(§7.5.2)時,只有包含該部分的命名空間using 指令被考慮。這將使得在不同部分的相同標識符表示不同的意義。
namespace N { using List = System.Collections.ArrayList;
partial class A { List x; // x具有類型 System.Collections.ArrayList } }
namespace N { using List = Widgets.LinkedList;
partial class A { List y; // y 具有類型 Widgets.LinkedList } }
|