C# 2.0 Specification (四)

這段比較短就先幹掉了:)

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 標識符<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

類型參數列表 可選 :基類 可選 類型參數約束語句 可選 類體;可選

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,IBIC


通常,在接口聲明的部分中提供接口的實現;但這不是必需的。一個部分可以爲聲明在另一個部分中的接口提供實現。

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
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章