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

第2章       命名规范

2.1.   大小写约

2.1.1.    标识符的大小写规则

    ü PascalCasing命名多个单词构成的命名空间、类型以及成员的名字。

    例如:使用TextColor而不使用Textcolor,单个单词(Button)的首字母大写,当一个单词为复合词(endpoint)作为一个单词,只有第一字母大写。

 

    ü camelCasing命名参数的名字。

 

    ü 不同类型标识符的大小写规则,如下表:

标识符

命名法

例子

命名空间

Pascal

nameSpace System.Scurity{...}

类型

Pascal

public class StreamReader{...}

接口

Pascal

public interface IEnumerable{...}

方法

Pascal

public class Object{
public virtual string Tostring();}

属性

Pascal

public class String{
public int Length {get;}}

事件

Pascal

public class Process{
public event EventHandler Exited;}

字段(静态)

Pascal

public class MessageQueue{
public static readonly TimeSpan InfiniteTimeout;}

枚举值

Pascal

FileMode{Append,...}

参数

Camel

public class Convert{
public static int ToInt32 (string value);}

2.1.2.    缩写词首字母的大小写

    ü 要把缩写词首字母为两个字母全部大写,当是camelCasing风格的参数名的作为第一单词来使用。

    例如:

    System.IO

    Public void StartIO(Stream ioStream)

 

    ü 把缩写词首字母为三个或三个以上字母第一字母大写,当是camelCasing风格的标识符作为第一单词来命名。

    例如:

    System.Xml

    Public void processHtmlTag(string htmlTag)

 

    ü 不要把camelCasing风格的标识符头部的任何首字母缩写词的任何字母大写,无论首字母缩写词的长度是多少。

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

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

 

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

 

    ü 常用的复合词和常用术语的大小写及拼写。如下表:

Pascal

Camel

Not

BitFlag

bitFlag

Bitflag

Callback

callback

CallBack

Canceled

canceled

Cancelled

DoNot

doNot

dont

Email

email

EMail

Endpoint

endpoint

EndPoint

FileName

fileName

Filename

Gridline

gridline

GridLine

Hashtable

hashtable

HashTable

Id

id

ID

Indexes

indexes

Indices

LogOff

logOff

LogOut

LogOn

logOn

LogIn

Metadata

metadata

MetaData,metaData

Multipanel

multipanel

MultiPanel

Multiview

multiview

MultiView

Namespace

namespace

NameSpace

Ok

ok

OK

Pi

pi

PI

Placehoder

placehoder

PlaceHoder

Signln

signln

SignOn

SignOut

signOut

SignOff

UserName

userName

Username

WhiteSpace

whiteSpace

Whitespace

Writable

writable

Writeable

 

2.1.4.    是否区分大小写

    ü 任何外部可访问的API不应该仅通过大小写来区分位于同一个上下文中的两个名字。

 

    ü 区分大小写只有一条规范:不要以为所有的编程语言都是区分大小写的,实际情况并非如此。不应该仅仅通过大小写来区分名字。

2.2.   通用命名的约定

2.2.1.    单词的选择

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

 

    ü 要更看重可读性,而不是更看重简短性。如属性名CanScrollHorizontally要胜过ScrollableX

 

    û 不要使用下划线、连字符以及其他任何既非字母也非数字的字符。

 

    û 不要使用匈牙利命名法。

 

    û 避免使用与广泛使用的编程语言的关键字有冲突的标识符。

2.2.2.    使用单词缩写和首字母缩写词

    û 不要使用缩写词和缩约词作为标识符名字的一部分。

例如:要用GetWindow,而不用GetWin

 

    û 不要使用未被广泛接受的首字母缩写词,即使是被广泛接受的首字母缩写词,也只应该在必需的时候才使用。

    例如:UI用来表示User InterfaceHTML用来表示Hypertext Markup Language。虽然

许多框架设计师认为一些新近的首字母缩写词很快就会被广泛接受,但在框架的标识

符中使用它们仍是不好的做法。

2.2.3.    避免使用语言特有的名字

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

    例如:GetLength这个名字比GetInt要好。

 

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

例如:一个把类型转换为System. Int64的方法应该被命名为ToInt64,而不是ToLong

(因为System. Int64CLR类型名,它对应于C#特有的别名long)。

 

    ü 语言特有的类型名及对应的CLR类型名,如下表:

C#

Visual Basic

C++

CLR

sbyte

SByte

char

SByte

byte

Byte

unsigned char

Byte

short

Short

short

Int16

ushort

UInt16

unsigned short

UInt16

int

Integer

int

Int32

uint

UInt32

unsigned int

UInt32

long

Long

_int64

Int64

ulong

UInt64

unsigned_int64

UInt64

float

Single

float

Single

double

Double

double

Double

bool

Boolean

bool

Boolean

char

Char

wchar_t

Char

string

String

String

String

object

Object

Object

Object

 

    ü 如果除了类型之外,标识符没有其他的语义,而且参数的类型不重要,要使用常见的名字,比如valueitem,而不要重复类型的名字。

    例如:下面是一个很好的例子,类提供的这些方法可以把各种不同的数据类型写入流中。

    void Write(double value);

    void Write(float value);

    void Write(short value);

2.2.4.    为已有API的新版本命名

    ü 要在创建已有API的新版本时使用与旧API相似的名字。

    例如:

    class AppDomain

    {

        [Obsolete(" AppDomain . SetCachePath  has  been  deprecated .          please use   AppDomainSetup . CachePath  instead. ")]

        public void SetCachePath(String path) { }

    }

    class AppDomainSetup

    {

        public string CachePath

        {

            get;

            set;

        }

}

 

    ü 要优先使用后缀而不是前缀来表示已有API的新版本。

 

    ü 考虑使用全新但有意义的标识符,而不是简单地给已有标识符添加后缀或前缀。

 

    ü 要使用数字后缀来表示已有API的新版本——如果已有API的名字是唯一有意义的名字(也就是说,它是一个工业标准),不适宜添加后缀(或改名.)。

    例如:

    //old API

    [ Obsolete("This  type  is  obsolete.  Please use  the new version of  the sarne class,X509Certificate2") ]

    public class X509Certificate  {  }

    //new API

    public class X509Certificate2 { }

 

    û 不要在标识符中使用“Ex”(或类似的)后缀来区分相同API的不同版本。

    例如:

    [Obsolete("This  type  is  obsolete  …")]

    public class Car { }

    //new API

    public class CarEx { }              // the wrong way

    public class CarNew { }            // the wrong way

    public class Car2 { }             // the right way

public class Automobile { }      // the right way

 

    ü 要在引入对64位整数(long)而非32位整数进行操作的新版API时使用“64”后缀只有当已经存在32位的API时才需要采用这种方法,对只有64位版本的全新API则不需要这样做。

    例如:SystemDiagnosticsProcess中有许多API返回Int32值来表示内存大小,比如PagedMemorySizePeakWorkingSet。为了在64位系统上也支持这些API,一些有相同名字但是带“64"后缀的API被加了进来。

    public class Process

    {

        // old APIs

        public int PeakWorkingSet { get; }

        public int PagedMemorySize { get; }

        // new APIs

        public long PeakWorkingSet64 { get; }

        public long PagedMemorySize64 { get; }

    }

2.3.   程序集和DLL的命名

    ü 要为程序集和DLL选择提示性的名字,比如System.Data,这样很容易就知道它的大致功能。程序集和DLL的名字不一定要和名字空间相对应,但在给程序集命名时遵循名字空间的名字也是合情合理的。.

 

    ü 考虑按照下面的模式给DLL命名:<Company>.<Component>.dll

    其中<Component>包含一个或多个以点号分隔的子句。

    例如:

    Microsoft.VisualBasic.dll

    Microsoft.VisualBasic.Vsa.dll

    Fabrikarn.Security.dll

    Litware.Controls.dll

2.4.   命名空间的命名

    ü 要用公司名称作为命名空间的前缀,这样就可以避免与另一家公司使用相同的名字。

    例如:微软提供的Microsoft Office自动化API应该放在Microsoft .Office命名空间中。

 

    ü 要用稳定的、与版本无关的产品名称作为命名空间的第二层。

 

    û 不要根据公司的组织架构来决定命名空间的层次结构,因为公司内部组织的名称一般来说不会持续太长的时间。

 

    ü 要使用PascaICasing大小写风格,并用点号来分隔名字空间中的各部分(例如Microsoft .Office.PowerPoint)。如果商标使用了非传统的大小写风格,那么即使该风格与常规的大小写风格相背,也还是应该遵循商标的大小写风格。

 

    ü 考虑在适当的时候在名字空间中使用复数形式。

    例如:要用System.Collections,而不要用System.Collection

    但是,商标名称和首字母缩写词例外。

    例如:要用System.IO,而不要用System.IOs

 

    û 不要用相同的名字来命名命名空间与位于该命名空间中的类型。

    例如:不要先将命名空间命名为Debug,然后又在该命名空间中提供一个名为Debug的类。许多编译器都要求用户在使用这样的类型时要加上完整的限定符。

2.5.   类、结构和接口的命名

    下面的命名规范适用于一般的类型命名:

    ü 要用名词或名词词组来给类型命名,在少数情况下也可以用形容词词组来给类型命名。在命名时要使用PascalCasing大小写风格。这要与方法命名区分开,方法命名用动词词组来命名。

 

    û 不要给类名加前缀(例如“C”)。

 

    ü 考虑让派生类的名字以基类的名字结尾。这样可读性会非常好,而且能清楚地解释它们之间的关系。

    例如:

Ø         ArgumentOutOfRangeException,它是一种Exception,以“Exception”结尾。

Ø         SerializableAttribute,它是一种Attribute,以“Attribute”结尾。

    但是,在运用这一条时,很重要的一点是要做出合理的判断。例如:即使Button类的名字中没有出现Control字样,它仍是一种Control事件。

    下面是一些正确命名的例子:

    public class FileStream : Stream { }

 public class Button : Control { }

 

    ü 要让接口的名字以字母I开头,这样可以显示出该类型是一个接口。

    例如:IComponent(描述性的名词)、ICustomAttributeProvider(名词短语)以及IPersistable(形容词)都是恰当的接口名字。同其他类型名一样,要避免使用单词缩写。

 

    ü 要确保一对类或接口的名字只相差一个“I”前缀,如果该类是该接口的标准实现。

下面以IComponent接口及其标准实现-Component类为例来说明本条规范。

    例如:

    public interface IComponent { }

    public class Component : IComponent { }

2.5.1.    泛型类型参数的命名

    ü 要用描述性的名字来命名泛型类型参数。如果泛型参数用一个字母即可清晰描述,就无需使用描述性名字命名。

    例如:

   public interface ISessionChannel<TSession> { }

public delegate TOutput Converter<TInput ,TOutput> {TInput  from}; 

public class List<T> { }

 

    ü 如果类型只有一个类型参数,且类型参数只有一个字母,考虑用T来命名参数类型。

    例如:

public int IComparer<T> { }

public  delegate 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

2.5.2.    常用类型的命名

    ü 要遵循下表中描述的规范——如果要从.NET框架的类型派生新类,或者要实现.NET

框架中的类型。

 

    ü 派生自或实现某些特定的核心类型的命名规则,如下表:

基类

派生类型/实现类型的规范

System.Attribute

要给自定义的attribute类添加"Attribute"后缀

System.Delegate

要给用于事件处理的委托添加"EventHandler"后缀

要给用于事件处理之外的那些委托添加"Callback"后缀

不要给委托添加"Delegate"后缀

System.EventArgs

要添加"EventArgs"后缀

System.Enum

不要派生自该类,要用编程语言提供的关键字来代替。
例如在c#中,要用enum关键字。

不要添加"Enum""Flag"后缀

Sytem.Exception

要添加"Exception"后缀

System.Collections.IDictionary

要添加"Dictionary"后缀。

System.Collections.Generic.
IDictionary<Tkey,TValue>

System.Collections.IEnumerable

要添加"Collection"后缀

System.Collections.ICollection

System.Collections.IList

System.Collections.Generic.
IEnumerable<T>

System.Collections.Generic.
ICollection<T>

System.Collections.Generic.IList<T>

System.IO.Stream

要添加Stream后缀

System.Security.CodeAccessPermission

添加Permission后缀

System.Security.IPermission

2.5.3.    枚举类型的命名

    ü 要用单数名词来命名枚举类型,除非它表示的是位域( bit field)

例如:

    public enum ConsoleColor

    {

        Black,

        Blue,

        Cyan

}

 

    ü 要用复数名词来命名表示位域的枚举类型,这样的枚举类型也称为标记枚举( flag enum)

    例如:

    [Flags]

        public enum ConsoleModifiers

        {

        Alt,

        Control,

        Shift

        }

 

    û 不要给枚举类型的名字添加“Enum”后缀。

    例如,下面的命名就不好:

    // Bad naming

    public enum ColorEnum

    {}

 

    û 不要给枚举类型的名字添加“Flag”或“Flags”后缀。

    例如,下面的命名就不好:

    //Bad  naming

    [Flags]

    public enum ColorFlags

{}

 

    û 不要给枚举类型值的名字添加前缀。

    例如:

    public enum ImageMode

    {

        ImageModeBitmap = 0,

        ImageModeGrayScale = 1,

        ImageModeIndexed = 2,

        ImageModeRgb = 3,

}

 

    下面的命名会更好:

    public enum ImageMode

    {

        Bitmap = O,

        GrayScale = 1.

        Indexed = 2,

        Rgb = 3,

    }

2.6.   类型成员的命名

2.6.1.    方法的命名

    ü 要用动词或动词词组来命名方法

    例如:

   public class String

    {

        public int CompareTo();

        public string[] Split();

        public string Trim();

    }

2.6.2.    属性的命名

    ü 要用名列、名词词组或形容词来命名属性。

    public class String

        {

        public int Length { get; }

        }

 

    û 不要让属性名看起来与“Get”方法的名字相似,

    例如:

    public string TextWriter{get{} set{}}

    public string GetTextWriter(int value){}

 

    ü 要用肯定性的短语(CanSeek而不是CantSeek)来命名布尔属性。如果有帮助,还可以有选择性地给布尔属性添加“Is”、“Can”或“Has”等前缀。

    例如:CanRead要比Readable更容易理解,但Created却比IsCreated的可读性更好。前缀通常是多余的,也没有必要,尤其是在有Intellisense的代码编辑器中。输入“MyObj ectEnabled=”与输入“MyObjectIsEnabled=”一样清楚,两种情况下Intellisense都会提示你选择truefalse,但后者更为冗长一些。

 

    ü 考虑用属性的类型名来命名属性

    例如:下面这个属性的作用是取得和设置一个名为Color的枚举值,因此它被命名为Color

    public enum Color{}

        public class Control

        {

        public Color Color{get{} set{}}

        }

2.6.3.    事件的命名

    ü 要用动词或动词短语来命名事件。

    例如:包括ClickedPaintingDroppedDown等等。

 

    ü 要用现在时和过去时来赋予事件名以之前和之后的概念。

    例如:在窗口关闭之前发生的close事件应该命名为Closing,而在窗口关闭之后发生

的应该命名为Closed

 

    û 不要用“Before”或“After”前缀或后缀来区分前置事件和后置事件。

 

    ü 要在命名事件处理函数(用作事件类型的委托)时加上”EventHandler”后缀,

    例如:

    public  delegate  void  ClickedEventHandler (object  sender,   ClickedEventArgs  e) ;

 

    ü 要在事件处理函数中用sendere作为两个参数的名字。参数sender表示触发该事件的对象。虽然参数sender可以是一个更为具体的类型,但一般来说其类型就是object。整个.NET框架一致地使用了这种模式。

    public  delegate void <EventName>EventHandler (object  sender,      <EventName>EventArgs  e);

 

    ü 要在命名事件的参数类时加上“EventArgs”后缀.

    例如:

    public class ClickedEventArgs : EventArgs

    {

        int x;

        int y;

        public ClickedEventArgs(int x, int y)

        {

            this.x = x;

            this.y = y;

        }

        public int x { get { return x; } }

        public int y { get { return y; } }

    }

2.6.4.    字段的命名

    ü 要在命名字段时使用PascalCasing大小写风格。

    例如:

   public class String

    {

        public static readonly string Empty;

    }

    ü 要用名词或名词短语来命名字段。

 

    û 不要给字段名添加前缀。

    例如:不要用“g_”或“s_”来区分静态和非静态字段

2.7.   参数的命名

    ü在命名参数时使用cameICasing大小写风格

    例如:

    public class String

    {

        public bool Contains(string value);

        public string Remove(int startIndex, int count);

}

 

    ü 要使用具有描述性的参数名。

    说明:参数名应该具备足够的描述性,使得在大多数情况下,用户根据参数的名字和类型就能够确定它的意思。

 

    ü 考虑根据参数的意思而不是参数的类型来命名参数。

    说明:开发工具必须向用户提供关于类型的有用信息,这样用户就能更好地利用参数名来描述语义,而不是描述类型。偶尔使用基于类型的参数名是完全可以的,但在采用这些规范时再回到匈牙利命名法则是绝对不应该的

2.8.   资源的命名

    ü 要在命名资源关键字( resource key)时使用PascalCasing大小写风格。

 

    ü 要使标识符的名字具有描述性而不是使名字变短。

 

    û 不要使用各主要CLR编程语言特有的关键字。

 

    ü 要在命名资源时仅使用字母、数字和下划线。

 

    ü 要用点号来给标识符清楚地划分层次。

    例如,如果要设计菜单系统的资源,那么可以考虑按下面的方式来命名它们:

    Menus.FileMenu.Close.Text

    Menus.FileMenu.Close.Color

    Menus.FileMenu.SaveAs.Text

    Menus.HelpMenu.About.Text

 

    ü 要在为异常的消息资源命名时遵循下面的命名约定。

    例如,资源标识符应该是异常的类型名加J-一个简短的异常标识符,之间以点号分隔:

    ArgumentException.IllegalCharacters

    ArgumentException.InvalidName

    ArgumentException.FileNameIsMalformed


你可能感兴趣的:(.NET设计规范(二) 命名规范)