C#2.0语言规范(五)不完全类型

规范

第五章 不完全类型
5.1 不完全声明
在定义一个分为多个部分的类型时,要使用一个新的类型修饰符——partial。为了保证和现有代码的兼容性,这个标识符和其他标识符不同:与get和set相同,它不是一个关键字,而且它必须直接出现在关键字class、struct和interface之一的前面。
class-declaration:
attributesopt class-modifiersopt partialopt class identifier type-parameter-listopt
class-baseopt type-parameter-constraints-clausesopt class-body ;opt
struct-declaration:
attributesopt struct-modifiersopt partialopt struct identifier type-parameter-listopt
struct-interfacesopt type-parameter-constraints-clausesopt struct-body ;opt
interface-declaration:
attributesopt interface-modifiersopt partialopt interface identifier type-parameter-listopt
interface-baseopt type-parameter-constraints-clausesopt interface-body ;opt
类声明:
特性可选 类修饰符可选 partial可选 class 标识符 类型参数列表可选
基类可选 类型参数约束条款可选 类体 ;可选
结构声明:
特性可选 结构修饰符可选 partial可选 struct 标识符 类型参数列表可选
结构接口可选 类型参数约束条款可选 结构体 ;可选
接口声明:
特性可选 接口修饰符可选 partial可选 interface 标识符 类型参数列表可选
基接口可选 类型参数约束条款可选 接口体 ;可选
不完全类型声明中的每一部分必须包含partial修饰符,并且必须和其他部分位于相同的命名空间中。partial修饰符表明在其他位置可能有该类型声明的附加部分,但这些附加部分不是必须的,这就运行一个单独的类型声明包含partial修饰符。
不完全类型的所有部分必须放在一起编译,这才能使这些部分在编译期间合并。但是部分类型不允许扩展已经编译过的类型。
嵌套类型可以通过使用partial修饰符声明为多个部分。典型的情况是,包含嵌套类型的类型的声明也使用了partial,而潜逃类型的各个部分分别声明在这个包含类型的各个不同部分中。
The partial modifier is not permitted on delegate or enum declarations.
partial修饰符不允许用于委托或枚举声明。
5.1.1 特性(Attribute)
不完全类型的各个部分上的特性将被按照不确定的顺序合并,如果一个特性被放在多个部分上,在相当于在类型上对一个特性使用了多次。例如,下面的两部分:
[Attr1, Attr2("hello")]
partial class A {}
[Attr3, Attr2("goodbye")]
partial class A {}
相当于下面的声明:
[Attr1, Attr2("hello"), Attr3, Attr2("goodbye")]
class A {}
类型参数上的特性按照同样的方式合并。
5.1.2 修饰符
当一个不完全类型声明中包含可访问性说明(public、protected、internal和private修饰符)时,所有其它部分都可以包含一个同样的修饰符。如果不完全类型的任何一个部分都不包含可访问性说明,这个类型将具有默认的恰当的可访问性。
如果嵌套类型的不完全声明中包含new修饰符,在这个嵌套类型隐藏了继承的成员时将不会出现警告。
如果类的不完全声明中的一个或多个部分包含了abstract修饰符,则这个类被认为是抽象的。否则,这个类被认为是非抽象的。
如果类的不完全声明中的一个或多个部分包含了sealed修饰符,则这个类被认为是密封的。否则,这个类被认为是非密封的。
注意一个类不能既是抽象的又是密封的。
当在不完全类型声明的一个部分上使用了unsafe修饰符,则只有这一个特定的部分被认为是在不安全环境中。
5.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>
{
...
}
是正确的,因为包含约束的部分(第一个和第二个)分别有效地对同一组类型参数指定了相同的一组类、接口和构造器约束。
5.1.4 基类
当一个不完全类声明中包含指定基类时,允许各个部分包含同样的指定基类。如果一个不完全类型的任何部分都未指定基类,则该类的基类为System.Object。
5.1.5 基接口
分别声明在不同部分中的基接口是指定在各个部分上的基接口的联合。一个特定的基接口在每个部分上只能命名一次,但允许在多个部分上命名同一个接口。基接口中的任何成员只能实现一次。
In the 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
{
...
}
5.1.6 成员
在多个部分中声明的成员只是每个部分中声明的成员的简单聚合。类型声明的所有部分中的类体共享相同的声明空间,并且每个成员的作用域都贯穿所有的部分。任何成员的可访问性总是包含了封闭类型的所有部分;在某一部分中声明的private成员可以在另一部分中自由地访问。如果在多个部分中声明了相同的成员则会产生编译错误,除非这个成员是一个用partial修饰符声明的类型。
partial class A
{
int x; // 错误,不能多次声明x
partial class Inner // 正确,这是一个不完全内部类型
{
int y;
}
}
partial class A
{
int x; // 错误,不能多次声明x
partial class Inner // 正确,这是一个不完全内部类型
{
int z;
}
}
尽管成员的顺序对于C#代码来说并不重要,但对于和其它语言或环境进行接口连接这可能是重要的。在这种情况下,在类型的多个部分中声明的成员的顺序是未定义的。
5.2 名字绑定
尽管可扩展的类型的各个部分必须声明在相同的命名空间中,但各个部分中可以写入不同的命名空间声明。因此,不同的using指令可以出现在各个部分中。当在一个部分中解释简单名字时,仅考虑该部分中声明的命名空间中的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
}
}

时间: 2024-10-07 16:09:55

C#2.0语言规范(五)不完全类型的相关文章

C#2.0语言规范(三)匿名方法

规范 第三章 匿名方法原著:Microsoft Corporation原文:http://msdn.microsoft.com/vcsharp/team/language/default.aspx (SpecificationVer2.doc)翻译:lover_P出处: -------------------------------------------------------------------------------- [内容] 3.1 匿名方法表达式 3.2 匿名方法签名 3.3 匿

C#2.0语言规范(四)迭代器

规范 4.1 迭代器块 一个迭代器块(iterator block)是一个能够产生有序的值序列的块.迭代器块和普通语句块的区别就是其中出现的一个或多个yield语句. yield return语句产生迭代的下一个值. yield break语句表示迭代完成. 只要相应的函数成员的返回值类型是一个枚举器接口(见4.1.1)或是一个可枚举接口(见4.1.2),一个迭代器块就可以用作方法体.运算符体或访问器体. 迭代器块并不是C#语法中的独立元素.它们受多种因素的制约,并且对函数成员声明的语义有很大影

C# 3.0语言新特性(语言规范):7 查询表达式

规范 原文:<C# Version 3.0 Specification>,Microsoft翻译:lover_P 查询表达式(Query Expression)为查询提供了一种语言集成的语法,这种语法类似于关系和分级查询语言,如SQL和XQuery. query-expression:from-clause  query-body from-clause:from  from-generators from-generators:from-generatorfrom-generators  ,

《Groovy语言规范》-语法

原文链接  译者:王山山 语法 本章节涵盖了Groovy编程语言的语法.Groovy语言的语法源自Java语法,为Groovy增强了特定构造,允许一定程度上的简化语法. 1.注释 1.1.单行注释 单行注释以//开始,在一行中任何位置都可以被发现.//后面的字符,直到一行的末尾都是注释的一部分. // a standalone single line comment println "hello" // a comment till the end of the line 1.2.多行

EJB3.0新规范概览及其未来发展

规范 引言 期待已久的EJB3.0规范在最近发布了它的初稿.在本文中将对新的规范进行一个概要性的介绍,包括新增的元数据支持,EJBQL的修改,实体Bean模型访问bean上下文的新方法和运行时环境等等.作者还讨论了EJB在未来要作出的调整以及EJB3.0与其他开发规范之间的关系. 开始 无论如何由于EJB的复杂性使之在J2EE架构中的表现一直不是很好.EJB大概是J2EE架构中唯一一个没有兑现其能够简单开发并提高生产力的组建. EJB3.0规范正尝试在这方面作出努力以减轻其开发的复杂性.EJB3

分清“语言/规范”以及“平台/实现”,以及跨平台.NET开发

在许多年前,"语言"就等同于"平台",例如C,C++以及最早的Ruby和Python等等.但是随着技术发展,出现了一些通用的平台,例如.NET和Java,逐渐这些平台上的语言也越来越多.再后来,某些语言在不同平台上的实现也越来越多,事情也变得有些复杂.技术在发展,但是从目前社区的讨论中,我发现许多朋友的观念还没有跟上.简单地说,如今的观念,一定要从"语言即平台"切换成"语言及平台",当分清"语言"和&quo

《Groovy语言规范》-语法(一)

语法 本章节涵盖了Groovy编程语言的语法.Groovy语言的语法源自Java语法,为Groovy增强了特定构造,允许一定程度上的简化语法. 1.注释 1.1.单行注释 单行注释以//开始,在一行中任何位置都可以被发现.//后面的字符,直到一行的末尾都是注释的一部分. // a standalone single line comment println "hello" // a comment till the end of the line 1.2.多行注释 一个多行注释以/*开

058_《突破Delphi7.0编程实例五十讲》

<突破Delphi7.0编程实例五十讲> Delphi 教程 系列书籍 (058) <突破Delphi7.0编程实例五十讲> 网友(邦)整理 EMail: shuaihj@163.com 下载地址: Pdf 作者: 张增强 丛书名: 万水编程实例五十讲丛书 出版社:中国水利水电出版社 ISBN:7508412761 上架时间:2002-12-21 出版日期:2002 年12月 开本:16开 页码:362 版次:1-1 内容简介 Delphi是面向对象的可视化编程语言,它是目前面向对

JAVA语言规范-线程和锁章节之同步、等待和通知

原文链接  本文是Oracle官方<Java语言规范>的译文 JAVA语言规范:线程和锁 1 同步 JAVA编程语言提供了线程间通信的多种机制.这些方法中最基本的是同步化,此方法是使用监视器实现的.JAVA中每个对象与一个监视器相关联,一个线程可以加锁和解锁监视器.一次仅有一个线程可能在监视器上持有锁.尝试锁住该监视器的任何其他线程被阻塞,直到它们可以再该监视器上获得一个锁.线程t可以多次锁住特别的监视器:每个解锁将一个加锁操作的作用反转来了. synchronized语句计算了一个对象的引用