第 4 章:类型设计规范

4.1 类型和命名空间

  要用命名空间把类型组织成一个由相关的功能区所构成的层次结构中。

  避免非常深的命名空间层次。因为用户需要经常回找,所以这样的层次浏览起来很困难。

  避免有太多的命名空间。

  避免把为高级方案而设计的类型和为常见编程任务而设计的类型放在同一个命名空间中。

  不要不指定类型的命名空间就定义类型。

  要把那些为基本命名空间提供设计时功能的类型放在带“.Design”后缀的命名空间中。

  要把那些为基本命名空间提供自定义权限的类型放在带“.Permissions”后缀的命名空间中。

  要把那些为基本命名空间提供互操作功能的类型放在带“.Interop”后缀的命名空间中。

  要把所有位于主互操作程序集中的代码放在带“.Interop”后缀的命名空间中。

4.2 类和结构之间的选择

  考虑定义结构而不要定义类 - 如果该类型的实例比较小而且声明周期比较短,或者是经常被内嵌在其它对象中。

  避免定义结构,除非该类型具有以下所有特征。

    它在逻辑上代表一个独立的值,与基本类型(int、double 等等)相似;

    它的实例的大小小于 16 个字节;

    它是不可变的;

    它不需要经常被装箱。

  

4.3 类和接口之间的选择

  要优先定义类而不是接口

  要用抽象类而不是用接口来解除契约与实现之间的耦合。

  要定义接口 - 如果需要提供多态层次结构的值类型的话。

  考虑通过定义接口来达到与多重继承相类似的效果。

  

4.4 抽象类的设计

  不要在抽象类型中定义公有的或内部受保护的构造函数。

  要为抽象类定义受保护的构造函数或内部构造函数。

  要为每个抽象类提供至少一个继承自该抽象类的具体类型。

  

4.5 静态类的设计

  要尽量少用静态类。

  不要把静态类当做是杂物箱。

  不要声明或覆盖静态类中的实例成员。

  要把静态类定义为密封的、抽象的,并添加一个私有的实例构造函数 - 如果编程语言不直接支持静态类。

  

4.6 接口的设计

  要定义接口 - 如果想让一组包括值类型在内的类型支持一些公共的 API。

  考虑定义接口 - 如果想让已经继承自其它基类的类型支持该接口提供的功能。

  避免使用记号接口(没有成员的接口)。

  要为接口提供至少一个实现该接口的类型。

  要为每个接口提供至少一个使用该接口的 API(一个以该接口为参数的方法,或是一个类型为该接口的属性)。

  不要给已经发行的接口再添加成员。

4.7 结构的设计

  不要为结构提供默认的构造函数。

  不要定义可变的值类型。

  要确保当结构实例的所有数据都为 0、false 或 null(如果合适)时,结构仍处于有效状态。

  要为值类型实现 IEquatable<T>。

  不要显式地扩展 System.ValueType,事实上大多数编程语言不允许这样做。

4.8 枚举的设计

  要用枚举来加强那些表示值的集合的参数、属性以及返回值的类型性。

  要优先使用枚举而不要使用静态常量。

  不要把枚举用于开放的集合(比如操作系统的版本、朋友的名字等)。

  不要提供为了今后使用而保留的枚举值。

  避免显示地暴露只有一个值的枚举。

  不要在枚举中包含 sentinel 值。

  要为简单枚举类型提供零值。

  考虑以 Int32 为载体来实现枚举(大多数编程语言的默认选择),除非下面的任何一条成立。

  要用复数名词或名词短语来命名标记枚举,用单数名词或名词短语来命名简单枚举。

  不要直接扩充 System.Enum。

  要对标记枚举使用 System.FlagsAttribute。不要把该修饰属性用于简单枚举。

  要用 2 的幂次方作为标记枚举的值,这样就可以使用按位 OR 操作来自由地组合他们。

  考虑为常用的标记组合提供特殊的枚举值。

  避免让创建的标记枚举包含某些无效的组合。

  避免把 0 用作标记枚举的值,除非该值表示“所有标记都被清除”,而且按下一条规范进行了适当地命名。

  要把标记枚举的 0 值命名为 None。对标记枚举来说,该值必须始终表示“所有标记均被清除”。

  考虑给枚举添加值,尽管要冒一点兼容性的风险。

  

4.9 嵌套类型

  要在想让一个类型能够访问外层类型的成员时才使用嵌套类型。

  不要用公共嵌套类型来进行逻辑分组,应该用命名空间来达到这一目的。

  避免公开地暴露嵌套类型。除非是只需在极少数的情况下声明嵌套类型的变量,比如派生子类时,或者其它需要定制的高级场景中。

  不要使用嵌套类型 - 如果该类型可能会被除了它的外层类型之外的类型引用。

  不要使用嵌套 - 如果需要让客户代码来实例化它们。如果某个类型具有公有构造函数,那么他不应该被嵌套在其它类型中。

  不要把嵌套类型定义为接口的成员,许多编程语言不支持这样做。

4.10 类型和程序集元数据

  要在包含公共类型的程序集中使用 CLSCompliant(true) 修饰属性。

  要在包含公共类型的程序集中使用 AssemblyVersionAttribute 修饰属性。

  考虑在程序集版本号中使用 <V>、<S>、<B>、<R> 的格式。其中 V 是主版本号,S 是服务版本号,B 是构建号,R 是构建修订号。

  要在程序集中使用下面的修饰属性来提供额外的信息。

  考虑在程序集中使用 ComVisible(false)。可供 COM 调用的 API 需要特别地设计。

  考虑在程序集这种使用 AssemblyFileVersionAttribute 和 AssemblyCopyrightAttribut,其目的是为了提供与程序集有关的额外信息。

《.NET 设计规范》第 4 章:类型设计规范的更多相关文章

  1. .NET设计规范————类型设计规范

    类型设计规范 从CLR的角度看,只有值类型和引用类型两种类型,但是从框架设计的角度我们把类型从逻辑上分了更多的组.如下所示: 类是引用类型的一般情况,占了框架中的大多情况,类的流行归于它支持面向对象的 ...

  2. Javascript权威指南——第二章词法结构,第三章类型、值和变量,第四章表达式和运算符,第五章语句

    第二章 词法结构 一.HTML并不区分大小写(尽管XHTML区分大小写),而javascript区分大小写:在HTML中,这些标签和属性名可以使用大写也可以使用小写,而在javascript中必须小写 ...

  3. 《JS权威指南学习总结--第三章类型、值和变量》

    第三章 类型.值和变量 内容要点 一.数据类型 1.在编程语言中,能够表示并操作的值的类型称做数据类型 2.JS的数据类型分为两类: 原始类型:数字.字符串和布尔值 对象类型 3.JS中有两个特殊的原 ...

  4. 20190908 On Java8 第十九章 类型信息

    第十九章 类型信息 RTTI(RunTime Type Information,运行时类型信息)能够在程序运行时发现和使用类型信息. Java 主要有两种方式在运行时识别对象和类信息: "传 ...

  5. 4.类型设计规范《.NET设计规范》

    类是引用类型的一般情况,占了框架中的大多情况,类的流行归于它支持面向对象的特征,以及它的普遍的适用性,基类和抽象类是两个特殊的逻辑分组,它们与扩张性有关. 由于CLR不支持多继承,接口类型可以用来模拟 ...

  6. 第六章 类型(class)和成员基础

    1. 概述 本章讲述如何在一个类型中定义不同种类的成员. 2. 名词解释 3. 主要内容 3.1 类型的各种成员 在一个类型中,可以定义0个或多个以下种类的成员: ① 常量:常量就是指出数据值恒定不变 ...

  7. C# 语言规范_版本5.0 (第4章 类型)

    1. 类型 C# 语言的类型划分为两大类:值类型 (Value type) 和引用类型 (reference type).值类型和引用类型都可以为泛型类型 (generic type),泛型类型采用一 ...

  8. Javascript权威指南阅读笔记--第3章类型、值和变量(1)

    之前一直有个想法,好好读完JS权威指南,便于自己对于JS有个较为全面的了解.毕竟本人非计算机专业出生,虽然做着相关行业的工作,但总觉得对于基础的掌握并没有相关专业学者扎实,正好因为辞职待业等原因,还是 ...

  9. C# Language Specification 5.0 (翻译)第四章 类型

    C# 语言的类型分为两大类:值类型(value type)和引用类型(reference type),而它们又都同时具有至少一个类型形参的泛型类型(generic type).类型形参(type pa ...

随机推荐

  1. java_web学习(六) request对象中的get和post差异

    1.get与post的区别 Get和Post方法都是对服务器的请求方式,只是他们传输表单的方式不一样. 下面我们就以传输一个表单的数据为例,来分析get与Post的区别 1.1 get方法  jsp中 ...

  2. 学习web前端技术的笔记,仅供自己查阅备忘,移动对font-size的控制(并非原创)

    假设根字体font-size的值是40px, 640/40=16,16就是px换算rem的值 function initHtmlFontSize(){ //获取可可视屏幕的宽度 var _width= ...

  3. HTML/CSS/JavaScript学习笔记【持续更新】

    HTML <font> 标签 定义和用法 <font> 规定文本的字体.字体尺寸.字体颜色. 实例 规定文本字体.大小和颜色: <font size="3&qu ...

  4. C/C++中__builtin_popcount()的使用及原理

    __builtin_popcount()用于计算一个 32 位无符号整数有多少个位为1 Counting out the bits     可以很容易的判断一个数是不是2的幂次:清除最低的1位(见上面 ...

  5. redis3.0 集群在windows上的配置(转)

    1. 安装Redis版本:win-3.0.501https://github.com/MSOpenTech/redis/releases页面有,我下载的是zip版本的:Redis-x64-3.0.50 ...

  6. 动态链接库(DLL)编写经验

    我首先说明DLL的生成方法,之后再补充一些特殊之处. 生成方法: 1.对需要导出的类,在头文件中添加 #ifdef CLASS _API #define CLASS_API _declspec(dll ...

  7. oracle创建函数和调用存储过程和调用函数的例子(区别)

    创建函数: 格式:create or replace function func(参数 参数类型) Return number Is Begin --------业务逻辑--------- End; ...

  8. 在Sql Server Intergration Service中设置Catalog下所部署所有项目的参数值

    在Sql Server 2012开始,微软给SSIS添加了Project Model这种新的项目类型,与之对应的是在Sql Server数据库引擎中引入了Intergration Services C ...

  9. APP测试时常用adb命令

    ADB全称Android Debug Bridge, 是android sdk里的一个工具, 用这个工具可以直接操作管理android模拟器或者真实的andriod设备(手机),故在其实工作可以给我们 ...

  10. 一致性哈希java实现

    值得注意的点 哈希函数的选择 murmur哈希函数 该函数是非加密型哈希,性能高,且发生哈希碰撞的概率据说很低 md5 SHA 可以选择guava包,提供了丰富的哈希函数的API 支持虚拟节点+加权, ...