Ce paragraphe est court, je vais donc m'en débarrasser d'abord :)
23 Types incomplets
23.1 Déclaration de type incomplète
Le nouveau modificateur de type partiel est utilisé dans plusieurs Définir un type dans la section. Pour garantir la compatibilité avec les programmes existants, ce modificateur est différent des autres modificateurs (tels que get et set) en ce sens qu'il ne s'agit pas d'un mot-clé et qu'il doit apparaître immédiatement avant le mot-clé class, struct ou 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 标识符 类型参数列表 可选 基接口 可选 类型参数约束语句 可选 接口体 ;可选)
Chaque partie d'une déclaration de type incomplète doit contenir le modificateur partiel et doit être déclarée dans le même espace de noms que les autres parties. Le modificateur partiel indique que des parties supplémentaires de la déclaration de type peuvent exister ailleurs, mais l'existence de telles parties supplémentaires n'est pas requise, il est également raisonnable d'inclure le modificateur partiel sur une seule déclaration de type ;
Toutes les parties d'un type incomplet doivent être compilées ensemble afin qu'elles puissent être fusionnées au moment de la compilation. En particulier, les types incomplets ne permettent pas d'étendre les types déjà compilés.
Les types imbriqués peuvent être déclarés à plusieurs endroits en utilisant le modificateur partiel. Généralement, le type conteneur (c'est-à-dire le type contenant le type imbriqué) est également déclaré à l'aide de partial, et les parties du type imbriqué sont déclarées dans différentes parties du type conteneur.
Le modificateur partiel ne peut pas être utilisé dans une déclaration de délégué ou d'énumération.
23.1 Propriétés
Les propriétés d'un type incomplet sont déterminées en combinant les propriétés des parties individuelles dans un ordre non spécifié. Si un attribut est placé dans plusieurs parties d'un type incomplet, cela équivaut à spécifier l'attribut plusieurs fois sur ce type. Par exemple, les attributs des deux parties
[Attr1, Attr2("hello")] partial class A {} [Attr3, Attr2("goodbye")] partial class A {} 等价于如下声明。 [Attr1, Attr2("hello"), Attr3, Attr2("goodbye")] class A {}
sur les paramètres de type sont également combinés dans le même style.
23.1.2 Modificateurs
Lorsqu'une déclaration de type incomplète contient des spécifications d'accès (publique, protégée, interne et privée), elle doit être cohérente avec les spécifications d'accès des autres parties. Si aucune partie d'un type incomplet ne contient de spécifications d'accès, le type reçoit une accessibilité par défaut appropriée (§3.5.1).
Si une ou plusieurs déclarations incomplètes d'un type imbriqué contiennent le nouveau modificateur, il n'y aura aucun avertissement si le type imbriqué cache un membre hérité. (§3.7.12)
Si une ou plusieurs déclarations incomplètes d'une classe contiennent le modificateur abstrait, alors la classe est abstraite (§10.1.1.1), sinon elle est non abstraite de.
Notez qu'un cours ne peut pas être à la fois abstrait et scellé.
Lorsque le modificateur unsafe est utilisé sur une déclaration de type incomplète, seule la partie spécifiée est considérée comme un contexte non sécurisé [contexte non sécurisé (§18.1))].
23.1.3 Paramètres et contraintes de type
Si un type générique est déclaré en plusieurs parties, chaque partie doit spécifier les paramètres de type. Chaque partie doit avoir le même nombre de paramètres de type, et chaque paramètre de type doit avoir le même nom et le même ordre.
Lorsqu'une déclaration générique incomplète contient une contrainte de paramètre de type (instruction Where), la contrainte doit être cohérente avec les contraintes des autres parties. En particulier, chaque partie contenant une contrainte doit avoir le même ensemble de paramètres de type pour la contrainte, et l'ensemble des contraintes de classe
, d'interface et de constructeur doit être le même pour chaque paramètre de type. Si aucune contrainte n'est spécifiée sur aucune partie d'un générique incomplet, les paramètres de type sont considérés comme sans contrainte.
L'exemple
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> { ... }
est correct car ces sections contenant des contraintes spécifient effectivement le même ensemble de classes, d'interfaces et de contraintes de constructeur pour le même ensemble correspondant de paramètres de type.
23.1.4 Classes de base
Lorsqu'une déclaration de classe incomplète contient une spécification de classe de base, elle doit être cohérente avec toutes les autres parties contenant la spécification de classe de base. Si une partie de la déclaration de classe incomplète ne contient pas de déclaration de classe de base, alors la classe de base sera System.Object (§10.1.2.1).
23.1.5 Interfaces de base
Une collection d'interfaces de base pour un type déclaré en plusieurs parties est une union des interfaces de base spécifiées dans chaque partie. Une interface de base spécifique ne peut être nommée qu'une seule fois dans chaque section, mais la même interface de base peut être nommée dans plusieurs sections. Mais il ne peut y avoir qu’une seule implémentation pour un membre d’interface de base donné.
En exemple
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 } }
以上就是C# 2.0 Specification (四)的内容,更多相关内容请关注PHP中文网(www.php.cn)!