今天终于有时间可以不用加班,回来看电影,听歌。筹划已久的博客,今天终于也迎来了第一篇有意义的文章,参考了网络上的一些文章,写的不好,再努力。
实际上命名规范是有很多的,也不是见到的就可以说的清楚,这里就就简单的介绍三种:匈牙利命名规范,Pascal,Camel:
一、匈牙利命名规范:广泛应用于象Microsoft Windows这样的环境中。
几年以前,Charles Simonyi(他后来成为微软的著名程序员)设计了一种以前缀为基础的命名方法,这种方法后来称为"匈牙利表示法"以记念他.他的思想是根据每个标识符所代表的含义给它一个前缀.微软后来采用了这个思想,给每个标识符一个前缀以说明它的数据类型.因此,整型变量的前缀是n,长整型变量是nl,字符型数组变量是ca,以及字符串(以空类型结尾的字符数组)以sz为前缀.这些名字可能会非常古怪.比如说:lpszFoo表示"Foo"是一个指向以空字符为结尾的字符串的长整型指针. 这种方法的优点是使人能够通过变量的名字来辨别变量的类型,而不比去查找它的定义.遗憾的是,这种方法不仅使变量名字非常绕口,而且使改变变量类型的工作变得十分艰巨.在Windows3.1中,整型变量为16为宽.如果我们在开始时采用了一个整型变量,但是在通过30---40个函数的计算之后,发现采用整型变量宽度不够,这时我们不仅要改变这个变量的类型,而且要改变这个变量在这30--40个函数中的名字. 因为不切实际,除了一些顽固的Windows程序员外已经没有人再使用"匈牙利表示法"了.毫无疑问,在某种场合它依然存在,但大部分人现在已经抛弃它了.一般而言,输入前缀是一种糟糕的想法,因为它把变量于其类型紧紧地绑在了一起. 对于30行以下的函数,匈牙利方法一般有优势。 尤其是对界面编程,有优势。 但对于有强烈的算法要求、尤其是有很多抽象类型的C++程序,匈牙利方法简直是一个灾难。 看你用在什么地方。 现在有了很好的IDE工具,如:VC,SourceInsight等. 选中变量,会自动提示告诉你它的声明和定义,这样 匈牙利命名法就没有很大的必要了. 无非就是为了程序可读性较好. 实际上良好的代码书写习惯比强制使用匈牙利命名法更重要. 系统性。整体性。可读性。分类要清楚。要有注释! 匈牙利命名法是微软推广的一种关于变量、函数、对象、前缀、宏定义等各种类型的符号的命名规范。匈牙利命名法的主要思想是:在变量和函数名中加入前缀以增进人们对程序的理解。它是由微软内部的一个匈牙利人发起使用的,结果它在微软内部逐渐流行起来,并且推广给了全世界的Windows开发人员。下面将介绍匈牙利命名法,后面的例子里也会尽量遵守它和上面的代码风格。还是那句话,并不是要求所有的读者都要去遵守,但是希望读者作为一个现代的软件开发人员都去遵守它。
匈牙利命名法通过在变量名前面加上相应的小写字母的符号标识作为前缀,标识出变量的作用域,类型等。这些符号可以多个同时使用,顺序是先m_(成员变量),再指针,再简单数据类型,再其他。例如:m_lpszStr, 表示指向一个以0字符结尾的字符串的长指针成员变量。
匈牙利命名法关键是:标识符的名字以一个或者多个小写字母开头作为前缀;前缀之后的是首字母大写的一个单词或多个单词组合,该单词要指明变量的用途。
匈牙利命名法中常用的小写字母的前缀:
前 缀 类 型
a 数组 (Array)
b 布尔值 (Boolean)
by 字节 (Byte)
c 有符号字符 (Char)
cb 无符号字符 (Char Byte,没有多少人用)
cr 颜色参考值 (ColorRef)
cx,cy 坐标差(长度 ShortInt)
dw Double Word
fn 函数
h Handle(句柄)
i 整型
l 长整型 (Long Int)
lp Long Pointer
m_ 类的成员
n 短整型 (Short Int)
np Near Pointer
p Pointer
s 字符串型
sz 以null做结尾的字符串型 (String with Zero End)
w Word
二、骆驼命名法(Camel)
骆驼式命令法,正如它的名称所表示的那样,是指混合使用大小写字母来构成变量和函数的名字,注意第一个单词是永远小写的,后面的单词首字母是大写,其余的就是小写。例如,下面是分别用骆驼式命名法和下划线法命名的同一个函数:
printEmployeePaychecks();
print_employee_paychecks();
第一个函数名使用了骆驼式命名法——函数名中的每一个逻辑断点都有一个大写字母来标记;第二个函数名使用了下划线法----函数名中的每一个逻辑断点都有一个下划线来标记。
骆驼式命名法近年来越来越流行了,在许多新的函数库和Microsoft
Windows这样的环境中,它使用得当相多。另一方面,下划线法是c出现后开始流行起来的,在许多旧的程序和UNIX这样的环境中,它的使用非常普遍。
好处很明显,可以很清晰的明白命名的意义,这也是编程命名的一个基本出发点。
三、帕斯卡(pascal)命名法:
与骆驼命名法类似。只不过骆驼命名法是首字母小写,而帕斯卡命名法是首字母大写
如:public void
DisplayInfo();
string UserName;
二者都是采用了帕斯卡命名法.
在C#中,以帕斯卡命名法和骆驼命名法居多。
总结下他们分别是在什么情况下使用:
1 匈牙利命名:一种古老的命名规范,在小的函数中可以使用,代码量很低。有现代的IDE工具就不需要的。但是程序员应该都能熟悉。
2 Camel命名: 可以多出使用,主要用法以c#参考:主要用于变量命名规范,函数的形参,变量,
3 Pascal命名: 同上,主要用在类型,函数名,文件名,
附上.NET命名规范中文版
避免使用由经常使用的名称空间复制的类型名。类型名不能使用下列词语。
System Collections Forms UI
避免使用与常用关键词冲突的标识符。例如,避免使用下列词语。
AddHandler | AddressOf | Alias | And | Ansi |
As | Assembly | Auto | BitAnd | BitNot |
BitOr | BitXor | Boolean | ByRef | Byte |
ByVal | Call | Case | Catch | CBool |
CByte | CChar | CDate | CDec | CDbl |
Char | CInt | Class | CLng | CObj |
Const | CShort | CSng | CStr | CType |
Date | Decimal | Declare | Default | Delegate |
Dim | Do | Double | Each | Else |
ElseIf | End | Enum | Erase | Error |
Event | Exit | ExternalSource | False | Finally |
For | Friend | Function | Get | GetType |
Goto | Handles | If | Implements | Imports |
In | Inherits | Integer | Interface | Is |
Let | Lib | Like | Long | Loop |
Me | Mod | Module | MustInherit | MustOverride |
MyBase | MyClass | Namespace | New | Next |
Not | Nothing | NotInheritable | NotOverridable | Object |
On | Option | Optional | Or | Overloads |
Overridable | Overrides | ParamArray | Preserve | Private |
Property | Protected | Public | RaiseEvent | ReadOnly |
ReDim | Region | REM | RemoveHandler | Resume |
Return | Select | Set | Shadows | Shared |
Short | Single | Static | Step | Stop |
String | Structure | Sub | SyncLock | Then |
Throw | To | True | Try | TypeOf |
Unicode | Until | Variant | When | While |
With | WithEvents | WriteOnly | Xor | eval |
extends | instanceof | package | var |
标识符(包括参数名)中 不要使用缩写。
如果必须使用缩写:
任何超过两个字符以上的缩写都使用camel大写格式,即使这不是标准缩写。
名称空间
命名名称空间的一般规则如下:
CompanyName.TechnologyName
这样,我们看到的名称空间应该是这样的:
Microsoft.Office
PowerSoft.PowerBuilder
注意:这只是一个原则。第三方公司可以选择其它的名字。
避免用公司名称或其它著名品牌的名称作为名称空间的前缀,这样会造成两个公布的名称空间有同一个名称的可能性。(例如,将微软提供的Office自动类命名为Microsoft.Office。)
使用Pascal大写方式,用逗号分隔逻辑成分(例如,Microsoft.Office.PowerPoint)。如果你的品牌使用的是非传统大写方式,那么一定要遵循你的品牌所确定使用的大写方式,即使这种方式背离了通常的名称空间大写规则(例如,NeXT.WebObjects,和ee.cummings。)
该用复数的时候要使用复数的名称空间名。例如,使用System.Collections而不是System.Collection。本规则的特例是品牌名称和缩写。例如:使用System.IO而不是System.IOs。
名称空间和类不能使用同样的名字。例如,有一个类被命名为Debug后,就不要再使用Debug作为一个名称空间名。
类和类成分
类的命名原则
用名词或名词短语命名类。
使用Pascal大写。
减少类名中缩写的使用量。
不要使用任何类前缀(比如C)。
不要使用带下划线的字符。
下面是一些正确命名的类名的例子。
public class FileStream {
}
public class Button {
}
public class String {
}
接口命名原则
使用名词或名词短语,或者描述行为的形容词来命名接口。例如,IComponent(描述性名词),ICustomAttributeProvider(名词短语),和IPersistable(形容词)。
使用Pascal大写。
减少接口名中缩写的使用量。
不要使用带下划线的字符。
在接口名前加前缀I,以表示这个类型是一个接口。
不要在类名前加上前缀C。偶而情况下,需要在类名前加上I而并不表示它是一个接口。在这种情况下,只要I后面的字符是小写就可(例如,IdentityStore。)
当类是接口的标准执行时,定义这一对类/接口组合就要使用相似的名称。两个名称的不同之处只是接口名前有一个I前缀。
下面我们举个例子,来看看接口IComponent和它的标准执行,类Component。
public interface IComponent {
}
public class Component : IComponent {
}
public interface IServiceProvider{
}
public interface IFormatable {
}
属性命名原则
在属性的后面加上Attribute后缀,来自定义属性类。如下例所示。
public class ObsoleteAttribute{
}
Enum 命名原则
Enum需使用Pascal大写。
Enum值名需使用Pascal大写。
减少enum名中缩写的使用量。
Enum名前不要加前缀(例如,adxxx表示ADO enums,rtfxxx表示多信息文本enum,等等。)。
在enum类型上不要加Enum后缀。
Enum名称需使用单数名词。
比特域使用复数名词。
如果列举值在参数或属性中使用,需用一个enum来定义列举值。这样工具就可以知道一个属性或参数可能的值了。
public enum FileMode{
Create,
CreateNew,
Open,
OpenOrCreate,
Truncate
}
如果数字值to be bitwise or'ed together,就使用Flags对属性进行自定义。
[Flags]
public enum Bindings {
CreateInstance,
DefaultBinding,
ExcatBinding,
GetField,
GetProperty,
IgnoreCase,
InvokeMethod,
NonPublic,
OABinding,
SetField
SetProperty,
Static
}
在封装一个Win32 API时,这个规则有一个特例。从一个Win32标头产生内部定义是很常见的。你可以使用Win32大写,这种形式下字母通常全部大写。
使用Int32作为一个enum的基础类型。
如果这个enum代表标志,而且标志又非常多(大于32),或者这个enum在将来可以发展成许多标志,或者类型需要与类型int有所不同以便向后兼容时,在这种情况下就产生了特例。
只有在值可以被完全表示为一组位标志时,才使用enum。开集不能使用enum(例如操作系统版,等等)。
只读和 Const 字段名
用名词,名词短语,或名词的缩写命名静态字段。
用Pascal大写命名静态字段。
不要用匈牙利文类型的符号作静态字段名的前缀。
参数名
使用描述性参数名。参数名应该具有足够的描述性,这样在大多数情况下参数名和它的种类可以用来确定它的意思。
用camel大写方式命名参数。
根据参数的意思来命名参数,而不是根据参数的种类来命名。我们希望开发工具可以用很方便的方式提供关于参数种类的信息,这样参数名可以得到更好的使用,可以对语义而不是对种类进行描述。但是偶尔使用根据类型命名的参数名也是完全可以的。
不要使用保留参数。如果在下一个版本中需要更多的数据,可以增加进来。
不要用匈牙利文类型的符号作为字段名的前缀。
Type GetType (string typeName)
string Format (string format, object [] args)
方法命名原则
用动词或动词短语命名方法。
用下述范例所示的Pascal大写方式命名方法。
RemoveAll()
GetCharArray()
Invoke()
属性命名原则
用名词或名词短语命名属性。
用Pascal大写命名属性。
属性与类型要一样。
用与一个类型的名称相同的名字来命名属性时,就使这个属性的类型成为那个类型。虽然听起来有些奇怪,但这是正确的。下面的例子正确使用了属性命名原则。
public enum Color {...}
public class Control {
public Color Color { get {...} set {...} }
}
下例就是不正确的。
public enum Color {...}
public class Control {
public int Color { get {...} set {...} }
}
在那个不正确的例子中,要想引用Color enum是不可能的,因为Color,Xxx会被翻译成一个成员访问,它会首先获得Color属性的值(int种类),然后再访问那个值的成员(它应该是System.Int32的一个实例成员)。
事件命名原则
用EventHandloer后缀命名事件处理程序,如下列所示。
public delegate void MouseEventHandler(object sender, MouseEvent e);
使用名为sender和e的两个参数。
Sender参数代表提出事件的对象。Sender参数永远是一个类型对象,即使它可能使用了更为特定的类型。
与事件相关的状态被封装在一个名为e的事件类范例中。要使用这个类型的正确的、特定的事件类。
public delegate void MouseEventHandler(object sender, MouseEvent e);
用EventArgs后缀命名事件自变量类,如下例所示。
public class MouseEventArgs : EventArgs {
int x;
int y;
public MouseEventArgs(int x, int y)
{ this.x = x; this.y = y; }
public int X { get { return x; } }
public int Y { get { return y; } }
}
命名事件名时,需要有之前和之后的时态概念,因此要使用现在时态和过去时态(不要使用BeforeXxx/AfterXxx的方式)。例如,可以被取消的结束事件就有Closing事件和Closed事件。
public event ControlEventHandler ControlAdded {
//..
}
用动词命名事件。
区分大小写
不要使用需要对大小写作出区分的名称。各成分不论是在区分大小写还是不区分大小写的语言下都必须是完全可用的。因为不区分大小写的语言不能在同样的环境下对只有大小写不同的两个名称作出辩别,所以成分必须避免这种情况。
不要产生两个名称相同只有大小写不同的名称空间。
namespace ee.cummings;
namespace Ee.Cummings;
带有两个参数的一个类型,其两个参数的名称不能只有大小写不同。
void foo(string a, string A)
System.WinForms.Point p;
System.WinForms.POINT pp;
带有两个属性的一个类型,其属性的名称不能只有大小写不同。
int Foo {get, set};
int FOO {get, set}
带有两种方法的一个类型,其方法的名称不能只有大小写不同。
void foo();
void Foo();
避免类型名出现混淆
不同的语言使用不同的术语以识别基本管理类型。设计人员必须避免使用对语言有专门要求的术语。遵照本章说明的规则,避免出现类型名称混淆的情况。
使用语义上有意义的名称,而不要使用类型名称。
在很少见的情况下,参数除了类型以外语义上没有任何意义,这时使用类属名。例如,一个类支持将多种数据类型写进一个流中,这个类可能有下列方法:
void Write(double value);
void Write(float value);
void Write(long value);
void Write(int value);
void Write(short value);
上面的例子在下述对语言有专门要求的情况下是首选。
void Write(double doubleValue);
void Write(float floatValue);
void Write(long longValue);
void Write(int intValue);
void Write(short shortValue);
在极端情况下,每一个基本数据类型需要有唯一的命名方式,此时使用下面的通用类型名称。
C# type name | Visual Basic type name | JScript type name | Visual C++ type name | IL representation | Universal type name |
sbyte | SByte | SByte | char | I1 | SByte |
byte | Byte | byte | unsigned char | U1 | Byte |
short | Short | short | short | I2 | Int16 |
ushort | UInt16 | UInt16 | unsigned short | U2 | UInt16 |
int | Integer | int | int | I4 | Int32 |
uint | NA | NA | unsigned int | U4 | UInt32 |
long | Long | long | __int64 | I8 | Int64 |
ulong | UInt64 | UInt64 | Unsigned __int64 | U8 | UInt64 |
float | Single | float | float | R4 | Single |
double | Double | double | double | R8 | Double |
bool | Boolean | boolean | bool | I4 | Boolean |
char | Char | char | wchar_t | U2 | Char |
string | String | String | String | System.String | String |
object | Object | Object | Object | System.Object | Object |
一个支持从流中读取多种数据类型的类可以有下列方法。
double ReadDouble();
float ReadSingle();
long ReadIn64();
int ReadInt32();
short ReadInt16();
上面的例子在下述对语言有专门要求的情况下是首选。
double ReadDouble();
float ReadFloat();
long ReadLong();
int ReadInt();
short ReadShort();