This paragraph is short so I’ll get rid of it first:)
23 Incomplete type
23.1 Incomplete type declaration
The new type modifier partial is used in multiple Define a type in the section. To ensure compatibility with existing programs, this modifier is different from other modifiers (such as get and set) in that it is not a keyword, and it must appear immediately before the keyword class, struct, or 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 标识符 类型参数列表 可选 基接口 可选 类型参数约束语句 可选 接口体 ;可选)
Each part of an incomplete type declaration must contain the partial modifier and must be declared in the same namespace as the other parts. The partial modifier indicates that additional parts of the type declaration can exist somewhere else, but the existence of such additional parts is not required; it is also reasonable to include the partial modifier on a single type declaration.
All parts of an incomplete type must be compiled together so that they can be fused at compile time. In particular, incomplete types do not allow extensions to already compiled types.
Nested types can be declared in multiple places by using the partial modifier. Typically, the containing type (that is, the type containing the nested type) is also declared using partial, and the parts of the nested type are declared in different parts of the containing type.
The partial modifier cannot be used in a delegate or enumeration declaration.
23.1 Properties
The properties of an incomplete type are determined by combining the properties of the individual parts in an unspecified order. If an attribute is placed in more than one part of an incomplete type, it is equivalent to specifying the attribute multiple times on that type. For example, the attributes on the two partial
[Attr1, Attr2("hello")] partial class A {} [Attr3, Attr2("goodbye")] partial class A {} 等价于如下声明。 [Attr1, Attr2("hello"), Attr3, Attr2("goodbye")] class A {}
type parameters are also combined in the same style.
23.1.2 Modifiers
When an incomplete type declaration contains access specifications (public, protected, internal and private), it must be consistent with the access specifications of other parts. If no parts of an incomplete type contain access specifications, the type is given appropriate default accessibility (§3.5.1).
If one or more incomplete declarations of a nested type contain the new modifier, and if the nested type hides an inherited member, there will be no warning. (§3.7.12)
If one or more incomplete declarations of a class contain the abstract modifier, then the class is abstract (§10.1.1.1), otherwise it is non-abstract of.
Note that a class cannot be both abstract and sealed at the same time.
When the unsafe modifier is used on an incomplete type declaration, only the specified part is considered unsafe context [unsafe context (§18.1))].
23.1.3 Type parameters and constraints
If a generic type is declared in multiple parts, each part must specify the type parameters. Each part must have the same number of type parameters, and each type parameter must have the same name and order.
When an incomplete generic declaration contains a type parameter constraint (where statement), the constraint must be consistent with the constraints in other parts. In particular, each section containing a constraint must have the same set of type parameters for the constraint, and the set of
class, interface, and constructor constraints must be the same for each type parameter. If no constraints are specified on any part of an incomplete generic, the type parameters are considered unconstrained.
Example
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> { ... }
is correct because these sections containing constraints effectively specify the same set of classes, interfaces, and constructor constraints for the corresponding same set of type parameters.
23.1.4 Base Classes
When an incomplete class declaration contains a base class description, it must be consistent with all other parts containing a base class description. If any part of the incomplete class declaration does not contain a base class declaration, then the base class will be System.Object (§10.1.2.1).
23.1.5 Base Interface
The set of base interfaces of a type declared in multiple parts is the union of the base interfaces specified in each part. A specific base interface can be named only once in each section, but the same base interface can be named in multiple sections. But there can be only one implementation for any given base interface member.
In example
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中文网(m.sbmmt.com)!