C# 编码标准:名称






3.25/5 (50投票s)
我们开发人员有时会忽略的 C# 中全面而重要的事实。
引言
当我查找泛型标准约定的时候,我偶然发现了一本 50 页的 C# 编码标准手册。我确信,除了作者本人,很少有人会真正去阅读完所有内容。因此,我想写下这篇文章。我尝试理解那些我们在 C# 开发中常常忽略的要点。我也会讨论一些常见的陷阱。
简洁、精炼、易懂。
我这样形容它。希望您阅读愉快。
为何要遵循编码标准
简单来说:可维护性。如果六个月后,您的客户对产品不太满意,并希望在您创建的应用程序中进行增强,您应该能够在不引入新 bug 的情况下完成。还有很多其他的好理由,但这是最让我们关心的。
不遵循任何标准就像采用临时解决方案(这可能导致永久性问题),正如您将看到的,牢记一些简单的措施比进行杂乱无章的编码付出的努力要少。
您所要做的就是一次性学习好的标准,并将它们牢记于心。相信我;这是值得的。
目录
- 命名 - 何为有意义的名称
- 大小写 - 何时使用 PascalCase,何时使用 camelCase
- 泛型 - 正确用法
- 委托 - 正确用法
- 杂项 - 一些简短的技巧
- 常见陷阱 - 我们应该注意的错误
- 参考 - 更多信息来源
命名
“智慧的开端是给事物贴上正确的名称” - 中国谚语
“有意义”是命名的关键词。有意义的名称,指的是简洁地准确描述变量、方法或对象的名称。让我们看看在 C# 中是如何实现的:
命名空间 - 名称应有意义且完整。指明您的公司或名称、产品,然后是您的工具。不要缩写。
//Good
namespace CompanyName.ProductName.Utility
//Bad
namespace CN.PROD.UTIL
类 - 类名应始终是名词,同样,应有意义。避免使用动词。
//Good
class Image
{
...
}
class Filters
{
...
}
//Bad
class Act
{
...
}
class Enhance
{
...
}
方法 - 除非方法操作其包含的类,否则始终使用动词-名词对;在这种情况下,只使用动词。
//Good
public void InitializePath();
public void GetPath();
public void ShowChanges();
public void System.Windows.Forms.Form.Show();
//Bad
public void Path();
public void Changes();
带返回类型的方法 - 名称应反映返回值。
//Good
public int GetImageWidth(Bitmap image);
//Bad
public int GetDimensions(Bitmap image);
变量 - 不要缩写变量名。变量名同样应具有描述性和意义。
//Good
int customerCount = 0;
int index = 0;
string temp = "";
//Bad
int cc = 0;
int i = 0;
string t = "";
私有成员变量 - 类成员变量前缀加上 m_
。
public class Image
{
private int m_initialWidth;
private string m_filename;
...
}
接口 - 所有接口名称前缀加上 I
。使用反映接口能力的名称,可以是通用的名词或以“able”结尾。
interface IClock
{
DateTime Time { get; set; }
...
}
interface IAlarmClock : IClock
{
void Ring();
DateTime AlarmTime { get; set; }
...
}
interface IDisposable
{
void Dispose();
}
interface IEnumerable
{
IEnumerator GetEnumerator();
}
自定义属性 - 所有属性类名称后缀加上 Attribute
。C# 编译器识别此模式,允许您在使用时省略它。
public class IsTestedAttribute : Attribute
{
public override string ToString()
{
return "Is Tested";
}
}
//"Attribute" suffix can be omitted
[IsTested]
public void Ring();
自定义异常 - 所有自定义异常名称后缀加上 Exception
。
public class UserNotExistentException :
System.ApplicationException
{
...
}
委托 - 所有事件处理程序后缀加上 Handler
;其他所有后缀加上 Delegate
。
public delegate void ImageChangedHandler();
public delegate string StringMethodDelegate();
大小写
C# 标准规定您使用特定的 Pascal 命名法(首字母大写)和 Camel 命名法(首字母不大写,其余单词首字母大写)模式。
Pascal 命名法 - 对类、类型、方法和常量使用 PascalCasing。
public class ImageClass
{
const int MaxImageWidth = 100;
public void ResizeImage();
}
enum Days
{
Sunday,
Monday,
Tuesday,
...
}
Camel 命名法 - 对局部变量和方法参数使用 camelCasing。
int ResizeImage(int imageCount)
{
for(int index = 0; index < imageCount; index++)
{
...
}
}
Generics
泛型,在 .NET 2.0 中引入,是能够统一处理不同类型值的类。
使用大写字母表示类型;不要使用“Type
”作为后缀。
//Good
public class Stack ‹T›
//Bad
public class Stack ‹t›
public class Stack ‹Type›
委托(Delegates)
使用委托推断而非显式委托实例化。
public delegate void ImageChangedDelegate();
public void ChangeImage()
{
...
}
//Good
ImageChangedDelegate imageChanged = ChangeImage;
//Bad
ImageChangedDelegate imageChanged =
new ImageChangedDelegate(ChangeImage);
对没有参数的匿名方法使用空括号。
public delegate void ImageChangeDelegate();
ImageChangedDelegate imageChanged = delegate()
{
...
}
杂项
- 避免在命名空间内放置
using
语句。 - 检查注释中的拼写。
- 始终将左花括号 { 放在新的一行。
- 将框架命名空间分组放在一起;在下方添加自定义和第三方命名空间。
- 使用严格的缩进(3 或 4 个空格,不要使用制表符)。
- 避免使用完全限定类型名称。
- 将注释缩进到与代码同一行。
- 所有成员变量都应声明在类的顶部;属性和方法之间应用一行空格分隔。
- 将局部变量声明在第一次使用它们的地方附近。
- 文件名应反映它们包含的类。
常见陷阱
让我们面对现实吧,我们有时都会这样做。让我们尽最大努力避免它们。
只有我们自己才懂的名称。
string myVar;
MyFunction();
单个或双字母变量名(局部变量可以理解)。
int a, b, c, a1, j1, i, j, k, ii, jj, kk, etc.
抽象的名称。
private void DoThis();
Routine48();
string ZimboVariable;
缩写。
//AcronymFunction
AF();
//SuperFastAcronymFunction
SFAT()
具有相似名称的不同函数。
DoThis();
DoThisWillYa();
以\ _ 开头的名称。它们看起来很酷,但让我们不要这样吧;)
int _m1 = 0;
string __m2 = "";
string _TempVariable = "";
具有微妙且无上下文意义的变量名。
string asterix = "";
// (this is the best function of all)
void God()
{
...
}
缩略语。
string num;
int abr;
int i;
参考文献
- 编码标准:C#
- 如何编写难以维护的代码
- C# 编码风格指南
- Juval Lowy - IDesign.NET
- 由 reinux 编辑(谢谢 rei)
感谢
感谢您阅读到这里。期待您宝贵的建议。请保重!
历史
- 2007 年 4 月 7 日:初次发布