3.命名规范

3.1 大小写约定

使用合适的大小写增强名字可读性。

3.1.1 标识符的大小写规则

标识符的每个单词首写字幕大写。不要用下划线。

  1. PascalCasing
  2. camelCasing

PascalCasing:约定用于除了参数名之外的所有标识符,它把标识符中每个单词的首字母(包括长度为两个字符以上的首字幕缩写词)大写,例子:

PropertyDescriptorHtmlTag

两个字母长的首字母缩写词是一个特例,在这种情况下两个字母都要大写:

IOStream

camelCasing:约定仅用于参数的名字,标识符中除第一个单词之外的所有单词首字母大写。

propertyDescriptorhtmlTag

ioStream (标识符以两个字母长的的首字母缩写词开始,两个字母都要小写)

标识符基本大小写规范:

要把Pascal Casing用于多个单词构成的名字空间、类型以及成员的名字。

要把Camel Casing用于参数的名字。

3.1.2 首字母缩写词的大小写

避免在标识符的名字中使用首字母缩写词是很重要的,除非他们很常用,能够被使用框架的人立刻理解,如:HTML、XML等。

从定义上讲首字母缩写词必须至少有两个字母。由三个或以上的字母组成的首字母缩写词遵循与其他单词一样的规范:只有第一个字母大写,除非是camelCasing风格的参数名中的第一个单词,在这种情况下两个字母都小写。如下所示:

Public void StartIO(Stream ioStream,boolcloseIOStream)
Public void PorcessHtmlTag(string htmlTag)
  • 把两个字母的首字母缩写词全部大写,除非它是 camelCasing 风格参数名的第一个单词。
System.IO
public void StartIO(Stream ioStream)
  • 把由三个或三个以上字母组成的首字母缩写词的第一个字母大写。只有第一个字母大写,除非首字母缩写词是 camelCasing 风格的标识符的第一个单词。
System.Xml
public void ProcessHtmlTag(string htmlTag)
  • × 不要 把 camelCasing 风格的标识符头部的任何首字母缩写词的任何字母大写,无论首字母缩写词长度是多少。

3.1.3 复合词和常用术语的大小写

在涉及大小写时,大多数复合词术语要作为单个单词处理。

× 不要 把所谓闭合形式的复合词中每个单词的首字母大写。

这些复合词要写成一个单词,比如 endpoint(末端)

Pascal Camel 不要写成
Endpoint endpoint EndPoint
BitFlag bitFlag Bitflag

3.1.4 是否区分大小写

× 不要 以为所有的编程语言都区分大小写,不应该仅仅通过大小写来区分名字。

3.2 通用命名约定

3.2.1 单词的选择

对于框架中标识符的名字最重要的一点是一目了然。名字意思清楚比长度短更重要,应该与场景、系统的逻辑组成物理组成以及为人熟知的概念相对应,不应该与技术或架构相对应。

  • 为标识符选择易于阅读的名字。

    例如,HorizontalAlignment 的属性比 AligemrntHorizontal 更易于阅读。
  • 更看重可读性,而不是更看重简洁性。

    CanScrollHorizontally(可以水平滚动) 胜过 ScrollableX(步太明显引用到了 X 坐标轴)
  • × 不要 使用下划线、连字符以及其他任何既非字母数字的字符。(私有字段可以使用,这与规范不冲突)
  • × 不要 使用匈牙利命名法。(int iMyAge; “i”是int类型的缩写;匈牙利命名法:开头字母用变量类型的缩写,其余部分用变量的英文或英文的缩写,要求单词第一个字母大写 )
  • × 避免 使用与广泛使用的编程语言的关键字有冲突的标识符。

3.2.2 使用单词缩写和首字母缩写词

  • × 不要 使用缩写词和缩略词作为标识符名字的组成部分。

    例如,要用 GetWindow,而不是用 GetWin
  • × 不要 使用未被广泛接受的首字母缩写词(即使是被广泛接受的首字母缩写词,也只应该在必须的时候才用。)

    例如,UI 用来表示 User InterfaceHTML 用来表示 Hypertext Markup Language

3.2.3 避免使用编程语言特有的名字

对那些所谓的基本类型,编程语言都有自己的名字。例如,int 是 C# 中 System.Int32 的别名。

  • 给类型名使用语义上有意义的名字,而不要使用语言特有关键字。

    例子,GetLengthGetInt 要好。
  • 使用 CLR 的通用类型名,而不要使用语言特有的别名 —— 如果除了类型之外,标识符没有其他语义。

    例子,类型转换为 System.Int64 的方法应该被命名为 ToInt64,而不是 ToLong
  • 使用常见的名字,比如 valueitem,而不要重复类型名字。

    例子,void Wirte(double value);

3.2.4 为已有的API的新版本命名

  • 在创建已有API的新版本时使用与旧API相似的名字,这有利于突出API之间的关系。
class AppDomain{}
class AppDomainSetup{}
  • 优先使用后缀而不是前缀来表示已有API的新版本。
ReaderWirterLock
ReaderWirterLockslim //正确
SlimReaderWirterLock //错误

有助于浏览文档或者使用 Intellisense 时发现新版本。

  • 考虑 使用全新但有意义的标识符,而不是简单地给已有标识符添加后缀或前缀。
  • 使用数字后缀表示已有 API 新版本 —— 如果已有 API 的名字是唯一有意义的名字,不适宜添加后缀。
//old API
public class X509Certificate{...}
//new API
public class X509Certificate2{...}
  • × 不要 在标识符中使用 Ex 后缀来区分相同API的不同版本。
public class Car{...}
//new API
public class CarEx {...} //错误方法
public class CarNew {...} //错误方法
public class Car2 {...} //正确方法
public class Automobile {...} //正确方法

3.3 程序集和 DLL 的命名

要记住,名字空间与DLL和程序集是不同的概念。名字空间对开发人员来说是一组逻辑实体,而DLL和程序集则是在打包和部署时的一个单元。

格式:<Company>.<Component>.dll

其中<Component>包含一个或多个以点号分隔的字句,如:

Microsoft.VisualBasic.dll

Microsoft.VisualBasic.Vsa.dll

3.4 名字空间的命名

<Company>.(<Product>|<Technology>)[.<Feature>][.<Subnamespace>]

  • 用公司名称作为名字空间的前缀。
  • 用产品名称作为名字空间的第二层。
  • × 不要 根据公司的组织架构来决定名字空间的层次结构,因为经过一段时间可能会变。
  • 使用 PascalCasing 。
  • 考虑 使用复数形式。
  • × 不要 用相同的名字命名空间和空间的类名。

名字空间与类型名的冲突

名字空间用来把类型组织成一个逻辑的、易于浏览的层次结构。对解决在导入多个名字空间时可能引起的类型名的二义性,它们是不可或缺的。

× 不要 引入太一般化的类型名(例如:Element,Node,Log,Message)

名字空间的类别如下:

  • 应用程序模型名字空间(application model namespace)

  • 基础设施名字空间(infrastructure namespace)

  • 核心名字空间(core namespace)

  • 技术名字空间组(technology namespace group)

1.应用程序模型名字空间

× 不要 给位于同一个应用程序模型的名字空间中的类型起相同的名字

例子,不要给 System.Web.UI.Adapters 命名空间增加一个名为 Page 的类型,因为 System.Web.UI 名字空间已经包含了一个名为 Page 的类型。

2.基础设施名字空间

这个类别包含了一些再开发常用的应用程序时很少会导入的名字空间。

3.核心名字空间

核心名字空间包含了所有的 System 名字空间,但应用程序模型名字空间和基础设置名字空间除外。(核心名字空间包括System、System.IO、System.Xml、System.NET等)

× 不要 给类型起会与核心名字空间中的任何类型产生冲突的名字。

例如:不要用 Stream 来作为类型名,它会和 System.IO.Stream 产生冲突

4.技术名字空间组

这个类别包括所有那些以相同的两个前缀(<Company>.<Technology>*)开始的名字空间(例如:Microsoft.Build.Utilities和Microsoft.Build.Tasks属于同一个技术类型,但是彼此之间不冲突)

× 不要 给类型会与位于同一技术组中的其他类型产生冲突的名字。

× 不要 在技术名字空间和应用程序模型名字空间的类型之间引入类型名冲突(例如:不应给Microsoft.VisualBasic名字空间增加一个Binding类型,因为System.Windows.Forms名字空间已包含该类型名)

3.5 类、结构和接口的命名

  • 类型名应该是名词词组,因为他们代表了系统中的实体,如果无法为类型找到一个名词词组,那么可能应该重新考虑该类型的总体设计。
  • 如果一个接口表示是类型层次的根基(如ILst<T>),那么它应该使用名词或名词短语。
  • 如果一个接口表示的是某种能力(如IComparable,IFormattable),那应该使用形容词或形容词短语。

  另一个重要的考虑因素是最易于识别的名字应该用于最常用的类型,应该反映出使用场景,而不是继承层次。

例如,Stream、StreamReader、TextReader、StringReader、FileStream 都相当好的描述每个类型在继承层次中的位置,但它们模糊对大多数用户来说最重要的信息:从文件中读取文本,哪个类型需要实例化。

  • 用名词或名词短语给类和结构命名。
  • 用形容词给接口命名,少数情况可以使用名词。、
  • × 不要 给类名加前缀。(唯一的前缀是用于接口“I”)
  • 考虑 在派生类的末尾使用基类的名字。
public class ArgumentOutOfRangeException:Exception {...}
public class FileStream: Stream {...}
public class Button: Control {...} //button 名字没出现 Control,但仍是一种 Control
  • 让接口的名字以I开头。
  • 确保一对类/接口的名字只相差一个“I”前缀,如果该类是该接口的标准实现。

3.5.1 泛型类型参数的命名

泛型是.NET框架2.0一个主要特征,它引入了一种称为“类型参数(type parameter)”的新标识符。以下的规范描述了与类型参数有关的命名约定。

  • 用描述性的名字来命名泛型类型参数,除非一个字母就说明含义就无需使用描述性名字。
public interface ISessionChannel<TSession> {...}
public delegte TOutput Converter<TInput,TOutput>(TInput from);
public class Nullable<T>{...}
  • 考虑 用单个字母 T 来命名参数类型 —— 如果类型只有一个类型参数并且类型参数只有一个字母。
public int IComparer<T> {...}
public delegte bool Predicate<T>(T item);
public struct Nullable<T> where T:struct{...}
  • 给描述性的类型参数加上 T 前缀。
public interface ISessionChannel<TSession> where TSession: ISession
{
TSession Session{get;}
}
  • 考虑 在类型参数名中显示出施加于该类型参数上的约束。

    例如,可以把一个被限制为 ISession 的类型参数命名为 TSession。

3.5.2 常用类型命名

如果要从.NET框架所包含的类型派生新类型,或者要实现.NET框架中的类型,要遵循下表的一个命名规则。如下所示:

3.5.3 枚举类型的命名

一般来说,枚举类型的命名应该遵循标准的命名规则(PascalCasing 大小写风格)。但是还有一些针对枚举类型的具体规范。

  • 单数名词来命名枚举类型,除非它表示的事位域(bit field)
  • 复数名词来命名表示位域的枚举类型,这样的枚举类型也称为标记枚举(flag enum)
[Flags]
public enum ConsoleModifiers{
Alt,
Control,
Shift
}
  • × 不要 给枚举类型的名字添加“Enum”后缀。
  • × 不要 给枚举类型的名字添加“Flag”后缀。
  • × 不要 给枚举类型值的名字添加前缀。
public enum ImageMode{
ImageModeBitmap=0,
ImageModeGrayScale=1,
ImageModeRgb=2
}

下面更好:

public enum ImageMode{
Bitmap=0,
GrayScale=1,
Rgb=2
}

3.6 类型成员的命名

3.6.1 方法的命名

因为方法是用来执行操作的,因此框架的设计规范要求方法名必须是动词或者动词词组。它还用来把方法同属性和类型名区分开,属性和类型名是名词或形容词词组。

尽量根据方法的对应任务来命名,不要根据一些实现细节。

3.6.2 属性的命名

与其他成员不同,属性应该用名词词组或形容词词组来命名。命名时要始终使用PascalCasing大小写风格。

  • 用名词、名词词组或形容词来命名属性。
  • × 不要 属性名看起来与“Get”方法的名字相似。
  • 用肯定性的短信(CanSeek而不是CantSeek)来命名布尔属性。如果有帮助,还可以有选择性的给布尔值属性添加“Is”,“Can”,“Has”等前缀。、
  • 考虑 用属性的类型名来命名属性。
public enum Color{…}
Public class Control{
Public Color Color{get{…} set{…}}
}

3.6.3 事件的命名

事件总是表示一些动作,要么正在发生,要么已经发生。因此和方法一样,要用动词来命名,此外,还要用动词的时态来表示事件发生的时间。

  • 动词或动词短语来命名事件。(例如:Clicked,DroppedDown等)
  • 用现在时和过去时来赋予事件名以之前和之后的概念。

    例如:在窗口关闭之前的close事件命名为Closing,关闭之后的事件命名为Closed。
  • × 不要 用“Before”或“After”前缀或后缀来区分前置和后置事件。
  • 在命名事件处理函数(用作事件类型的委托)时加上 EventHandler 后缀。
public delegate void ClickedEventHandler(object sender,ClickedEventArgse);
  • 在事件处理函数中用 sendere 作为两个参数的名字。

    参数sender表示触发该事件的对象。一般为 object
  • 在命名事件的参数类时加上 EventArgs 后缀。
public class ClickedEventArgs : EventArgs{
int x;
int y;
public ClickedEventArgs(int x,int y)
{
this.x =x; this.y =y;
}
...
}

3.6.4 字段的命名

字段的命名规范适用于静态共有字段和静态受保护字段。(未涵盖内部字段和私有字段)

  • 在命名字段时使用PascalCasing大小写风格。
  • 用名词或名词短语来命名字段。
  • × 不要 要给字段名添加前缀。(例如:不要用“g_”或”s_”来区分静态和非静态字段)

3.7 参数的命名

  • 在命名参数时使用camelCasing大小写风格。
  • 使用具有描述性的参数名。
  • 考虑 根据参数的意思而不是参数的类型来命名参数。

重载操作符的参数命名

  • 使用 leftright 来命名重载二元操作符的参数——如果参数没有具体的含义。
public static TimeSpan operator-(DateTimeOffset left,DateTimeOffset right);
public static bool operator==(DateTimeOffset left,DateTimeOffset right);
  • 使用 value 来命名重载一元操作符的参数——如果参数没有具体的含义。
  • 考虑 使用有意义的名字来命名。
  • × 不要 在命名重载操作符的参数时,使用缩写和数字编号。

3.8 资源的命名

本地化的资源就好比是属性,可以通过特定的对象来引用。因此资源的命名规范与属性的命名规范相似。

  • 在命名资源键(resource key)时使用PascalCasing大小写风格。
  • 使标识符的名字具有描述性而不是使名字变短。
  • × 不要 使用各种CLR编程语言特有的关键字
  • 在命名资源时仅使用字母、数字和下划线。
  • 在为异常的消息资源命名时遵循下面的命名约定:

    资源标识符应该是异常的类型名加上一个简短的异常标识符:
ArgumentExceptionIllegalCharacters
ArgumentExceptionInvalidName

3.命名规范《.NET设计规范》的更多相关文章

  1. Web UI 网站用户界面设计命名规范

    Web UI 网站用户界面设计命名规范 WEB UI设计命名规范,也就是网站用户界面设计(网页设计)命名规范. 这套规范并非单纯的CSS.html或JavaScript命名规范,它涉及了很多使用Pho ...

  2. .NET设计规范————命名规范

    NET设计规范:约定.惯用法与模式———命名规范 前言:          最近在看<.NET设计规范:约定.惯用法与模式>一书,主要还是讲.NET的设计规范,以前对这一块也不是特别在意, ...

  3. 《.NET 设计规范》第 3 章 命名规范

    <.NET 规范>第 3 章 命名规范 3.1 大小写约定 要把 PascalCasing 用于由多个单词构成的命名空间.类型以及成员的名字. 要把 camelCasing 用于参数的名字 ...

  4. NET设计规范(二) 命名规范

    http://blog.csdn.net/richnaly/article/details/6280294 第2章       命名规范 2.1.   大小写约定 2.1.1.    标识符的大小写规 ...

  5. mysql命名规范

    1.数据库表命名规范: (1)表名前应该加上前缀,表的前缀一个用系统或模块的英文名称缩写,前缀全部大写或首字母大写,表名中包含的单词首字母大写. (2)数据库表名应该有意义,并且易于理解,最好使用可以 ...

  6. JavaScript var关键字、变量的状态、异常处理、命名规范等介绍

    本篇主要介绍var关键字.变量的undefined和null状态.异常处理.命名规范. 目录 1. var 关键字:介绍var关键字的使用. 2. 变量的状态:介绍变量的未定义.已定义未赋值.已定义已 ...

  7. Java命名规范

    驼峰法则: 将所有字母都小写(包括缩写),然后将单词的第一个字母大写. 每个单词的第一个字母都大写,来得到大驼峰式命名. 除了第一个单词,每个单词的第一个字母都大写,来得到(小)驼峰式命名. 为避免歧 ...

  8. JavaScript知识点总结(命名规范,变量的作用域)

    命名规范 有人说JavaScript的宽容性是这个语言最糟糕的方面之一.比如说想把2个数字加在一起,JavaScript会把其中一个数字解析成字符串,那么就会得到一个奇怪的字符串,而不是2个数字的和. ...

  9. js的命名规范

                   js的命名规范   1.驼峰命名法:首字母是小写的,接下来的字母都以大写字符开头.例如: var testValue = 0; var oneValue = 10; 2. ...

随机推荐

  1. python自动化之excel

    import openpyxl wb=openpyxl.load_workbook(r'C:\Users\Administrator\Desktop\sl.xlsx') type(wb) wb.get ...

  2. 【设计模式】—— 解释器模式Interpret

    前言:[模式总览]——————————by xingoo 模式意图 自定义某种语言后,给定一种文法标准,定义解释器,进行解析. 做过搜索的朋友们可能更了解一些,平时我们搜索所需要的词库,通常就需要用这 ...

  3. 【大数据】Spark内核解析

    1. Spark 内核概述 Spark内核泛指Spark的核心运行机制,包括Spark核心组件的运行机制.Spark任务调度机制.Spark内存管理机制.Spark核心功能的运行原理等,熟练掌握Spa ...

  4. BZOJ2568 比特集合(树状数组)

    考虑维护f[k][x]表示“最低k位所表示的数不大于x”的数的个数.那么查询时答案就为f[k][2k-1]-f[k][2k-1-1]. 同时记录每个数在集合中出现多少次.这样的话插入.删除已经解决了, ...

  5. 洛谷P4338 [ZJOI2018]历史(LCT,树形DP,树链剖分)

    洛谷题目传送门 ZJOI的考场上最弱外省选手T2 10分成功滚粗...... 首先要想到30分的结论 说实话Day1前几天刚刚刚掉了SDOI2017的树点涂色,考场上也想到了这一点 想到了又有什么用? ...

  6. 后Hadoop时代的大数据技术思考:数据即服务

    1. Hadoop 的神话正在破灭 IBM leads BigInsights for Hadoop out behind barn. Shots heard IBM has announced th ...

  7. Python Django性能测试与优化指南

    摘要:本文通过一个简单的实例一步一步引导读者对其进行全方位的性能优化.以下是译文. 唐纳德·克努特(Donald Knuth)曾经说过:“不成熟的优化方案是万恶之源.”然而,任何一个承受高负载的成熟项 ...

  8. 【BZOJ3489】A simple rmq problem(KD-Tree)

    [BZOJ3489]A simple rmq problem(KD-Tree) 题面 BZOJ 题解 直接做肯定不好做,首先我们知道我们是一个二维平面数点,但是限制区间只能出现一次很不好办,那么我们给 ...

  9. Qtree4——动态点分治

    题目描述 给出一棵边带权的节点数量为n的树,初始树上所有节点都是白色.有两种操作: C x,改变节点x的颜色,即白变黑,黑变白 A,询问树中最远的两个白色节点的距离,这两个白色节点可以重合(此时距离为 ...

  10. Flink入门训练--以New York City Taxi为例

    最近在学Flink,准备用Flink搭建一个实时的推荐系统.找到一个好的网站(也算作是flink创始者的官方网站),上面有关于Flink的上手教程,用来练练手,熟悉熟悉,下文仅仅是我的笔记. 1. 数 ...