[书籍]重温《Framework Design Guidelines》

最近重温了《Framework Design Guidelines》。

《Framework Design Guidelines》中文名称为《.NET设计规范 约定、惯用法与模式》,简介如下:

数千名微软精锐开发人员的经验和智慧,最终浓缩在这本设计规范之中。与上一版相比,书中新增了许多评注,解释了相应规范的背景和历史,从中你能聆听到微软技术大师Anders Hejlsberg、Jeffrey Richter和Paul Vick等的声音,读来令人兴味盎然。

当年第一次读时茅塞顿开,现在重温还是获益良多。虽是一本十年前的书,仍是值得推荐给初学者阅读的一本好书。

2. 常见被违反的规范

今年升级一个核心代码从很久以前的代码改写过来的软件,各种不符合C#代码规范的代码让我感到难以维护;去年系统工程师退休前留给我们的一个代码更是让我受到会心一击。我使用C#多年来见到过很多不规范的代码,于是试着参考书中的规范,列出其中一些来常见的错误以及一些问题。

2.1 命名

把PascalCasing用于由多个单词构成的名字空间、类型以及成员的名字。
把camelCasing用于参数的名字。
不要使用匈牙利命名法。

也就是说参数要用camelCasing,其它所有能让使用者看到的地方,包括命名空间、类名称、属性、函数等都要都要使用PascalCasing。(除非是ex、e、i等约定俗成的用法,或者其他特殊情况如工业标准、商标、历史问题、遗留代码、调用非托管代码等。)

由于习惯问题,现在还经常见到匈牙利命名法如btnOk、strPwd,应修改为OkButton和Password。

在命名字段时使用PascalCasing大小写风格。(适用于静态公有字段和静态受保护字段)
不要提供共有的或受保护的实例字段。

.NET Core有更详细的# Coding Style:

We use _camelCase for internal and private fields and use readonly where possible. Prefix internal and private instance fields with _, static fields with s_ and thread static fields with t_. When used on static fields, readonly should come after static (e.g. static readonly not readonly static). Public fields should be used sparingly and should use PascalCasing with no prefix when used.

虽然写得很复杂,但我建议只有private的字段、常量字段和静态只读字段。能被外部修改的字段是危险的,所以字段应该只有如下几种形式:

private readonly string _id; private string _userName; private static bool s_valid = false; public const int MaxValue = 0x7fffffff; public static readonly Color Red = new Color(0x000FF);

在命名资源键(Resource Key)时使用PascalCasing大小写风格。

可是,我不觉得微软自己有遵循这个规范啊。

总的来说,框架中除了函数的参数外所有可见的部分都应该使用PascalCasing风格,因为资源通常可以以属性的方式被使用,所以资源的Key应该使用Pascal。可能因为很多时候资源的生成方式都是internal所以很多人都不遵守这个规范。

在命名异常消息的资源时遵循下面的命名约定。
资源标识符应该是异常的类型名加上一个简短的异常标识符:
ArgumentExceptionIllegalCharacters
ArgumentExceptionInvalidName
ArgumentExceptionFileNameIsMalfrmed

我觉得这条规范也适用于一般的错误信息,我常常见到CreateUserErrorMessage1、CreateUserErrorMessage2这种资源名称,改成CreateUserErrorInvalidUserName、CreateUserErrorInvalidPassword会比较好。

避免在命名基类时使用“Base”后缀 -- 如果公共API中会用到这个类。

[书籍]重温《Framework Design Guidelines》

但是微软自己的框架中就一大堆啊?不过这些都不常用,给一般用户的API最好还是要遵守这条规范。

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

我觉得dont-前缀真的挺常见的,.NET Core的源码里能搜出一大堆。无论如何我还是建议用肯定性的短语,否定性短语让人混淆。

2.2 属性

在下列情况中使用方法而不要使用属性

该操作比字段访问要慢记个数量级。

该操作返回一个数组。

这条规范有很多种情况,我只列出常见的两种容易犯错的情况。

第一种情况在WPF尤其常见,因为对XAML来说可以用于绑定的属性好用很多,所以很多应该是方法的地方都使用属性实现。

第二种情况在老代码里很常见,别说返回数组,把数组做成全局变量大家一起复用都很常见,也许是因为当年内存很贵?

2.3 枚举

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppdzz.html