[Framework Desgin Guideline]命名规范(2)
1. Assembly和dll的命名
dll的命名最好能表示程序集内的主体功能。
程序集/dll可以和命名空间的名字保持一致,但不强制要求一致。可以用命名空间的公共前缀作为程序集的名字,比如一个程序集主要包含两个命名空间:MyCompany.MyTechnology.FirstFeature 和 MyCompany.MyTechnolofy.SecondFuture,我们可以将程序集命名为MyCompany.MyTechnology。
可以考虑用这种方式对程序集进行命名: <Company>.<Compenent>.dll
2. Namespace的命名
Namespace命名的一般规则:<Company>.<Product>|<Technology>[.<Feature>][.<Subnamespace>]
使用公司名字作为namespace的前缀,避免和其他公司namespace的命名冲突。
在namespace的第二部分,即<Product>|<Technology>,应该使用一个稳定的,不会随版本变化的名字。
namespace的命名不应该依赖于公司的组织架构或者团队。因为组织架构和开发团队可能经常会发生改变,应该尽可能使namespace的命名和技术相关。
在合适的时候,使用复数对namespace进行命名。
比如:微软使用System.Collections, 而不是 System.Collection
在namespace当中不要定义和namespace同名的类型。
Namespace和类型之间的命名冲突
不要太一般的命名,或者说类型太弱的命名,比如:Element, Node, Log, Message等。这些命名极容易导致命名冲突。
为了避免命名冲突,根据不同的namespace类型,还有一些特殊的命名规范,Namespace大致可以分为四种:
Application model namespace 表示应用程序模式的namespace
比如 System.Window* 代表了winform的应用程序,System.Web.UI* 代表了webform的应用程序。
不要在同一种应用程序模式下,定义名称相同的类型。
Infrastructure namespace 标识程序结构的命名空间。
比如*.Design 代表这个namespace下是设计相关的功能, *.Permissions标识这个命名空间下主要是权限相关的功能。
这类namespace在一般的场景,并不太会被引入常用程序中,所以和他们的命名冲突出现概率会相对较小。
Core namespaces 类库核心功能的namespace
比如System, System.IO, System.Xml等。 永远不要定义和这些namespace以及其包含的类型,有命名冲突的命名。
Technology namespace groups 命名空间组
命名空间组是指,前两个节点相同的命名空间。比如:Microsoft.Build.Utilities和Micorsoft.Build.Tasks。
属于同一个命名空间组的类型,最好也不要有命名冲突。
3. 类型的命名
class, struct, interface的命名
一般来说,Class/Struct应该都是名词或者名词短语,因为他们代表了一个系统实体。
如果你找不到一个合适的名词或者名词短语为你的Class/Struct命名,那么你应该重新考虑一下你这个Class/Struct设计的是否合理。
Interface表现为一个层级的根节点的时候,可以是名词,比如IList<T>。
Interface表现为代表一种的能力的时候,表示为形容词,比如:IComparable<T>, IFormattable。
在命名的时候,另外一个重要的原则就是:把最容易识别的名字留给最常用的类型。
Interface是用字母"I”作为前缀。
当定义一个 class-interface对的时候,如果class是interface的标准实现,则class和interface只通过I前缀进行区分。
比如:
public interface IComponent { }
public class Component : IComponent { }
泛型类型的命名
为泛型成员定义一个可以自描述的名字,除非single-letter的名字完全能够自描述,并且添加多余的描述无意义。
例如:
public delegate TOutput Converter<TInput, TOutput>(TInput from);
使用T作为single-letter的泛型成员命名。
例如:
public class Nullable<T> { }
继承自基类的类型命名
在继承和实现基类的时候,使用某些类型作为基类的时候,需要添加基类作为类型的后缀。
比如:
public class RequestException : Exception { }有些类型则不需要添加父类名字作为后缀。
比如:
public class DropDownList : Control { }
是否需要参加后缀,可参照下面这个列表:
System.Attribute 添加Attribute后缀 System.Delegate 当delegate是event的时候添加EventHandler后缀
不是event的时候添加CallBack后缀
不要添加Delegate后缀System.EventArgs 添加EventArgs后缀 System.Enum 不要添加Enum后者Flag后缀 IDictionary
IDictionary<TKey, TValue>添加Dictionary后缀 IEnumerable
IEnumerable<T>
ICollection
IColletion<T>
IList
IList<T>添加后缀Collection System.IO.Stream 添加后缀Stream CodeAccessPermission
IPermission添加后缀Permission
枚举的命名
枚举的命名使用单数,除非使用了FlagAttribute。
public enum ConsoleColor { Black, Blue, Cyan }
如果使用了FlagAttribute,则使用复数。
[Flags] public enum ConsoleModifiers { Alt, Control, Shift }
不要添加Enum或者Flag后缀
不要添加枚举名称作为枚举项的前缀
比如这个例子是不合适的:
public enum ImageMode{
ImageModeBitmap = 0,
ImageModeGrayscale = 1
}
成员的命名
方法:
方法的名字应该是动词或者动词短语。
属性:
属性名字应该是名词、名词短语或者形容词。
不要定义和Get Method含义相同的属性。
比如下面这种命名是不合适的:
public string Name { get; set; }
public string GetName(int value) { };
对于集合属性,使用复数形式,不要添加Collection或者List后缀。public class ListView{
//good namingpublic ItemCollection Items { get; }
//bad namingpublic ItemCollection ItemCollection { get; }
}
对于Boolean属性,应该使用肯定的短语。比如:应该应该命名CanSeek, 而不是CantSeek。
在必要的时候,可以添加Is Can Has等前缀,不过要看具体情况。比如,IsCreated就不如Created可读性强。
可以考给属性和其类型相同的命名。
public enum Color { }public class Control{
public Color Color { get; set; }
}
事件:
Event使用动词和动词短语命名。比如:Clicked, Painting
使用现在时和过去时命名,不要使用before或after等前缀。
定义Event的时候,给Event加上EventHandler后缀,把两个参数分别命名为sender和e。
public delegate void <EventName>EventHandler (object sender, <EventName>EventArgs e);
Field:这里对Field的命名规则都是针对静态field或者protected的成员,不适用与Internal和private的field。
使用PascalCasing命名规则
public static readonly string Empty="";
public const Min = 0;
使用名字、名词短语、形容词
不要使用前缀。
参数的命名
参数使用camelCasing命名规则
使用很强自我描述性的命名
参数的命名应该更倾向于所代表的语义,而不是参数成员的类型。
运算符重载中的参数命名
在二元操作符中的两个参数,分别使用left和right命名。比如:
public static bool operator ==(int left, int right);
在一元操作符中,使用value命名参数。
public static int operator -(int value);
如果有更能表达语义的参数命名,也可以考虑使用。
比如下面这个场景:
public static decimal operator /(decimal dividend, decimal divisor);
不要使用缩写或者数字需要表命名成员参数。
下面这个运算符重载中的参数命名不太合适:
public static bool operator ==(DateTimeOffset d1, DateTimeOffset d2);