[书籍]重温《Framework Design Guidelines》 (2)

用单数名词来命名枚举类型,除非它表示的是位域(bit field)。
用复数名词来命名表示位域的枚举类型,这样的枚举类型也称为标记枚举(flag enum)。
不要给枚举类型的名字添加“Enum”后缀。
不要给枚举类型的名字添加“Flag”或“Flags”后缀。
不要给枚举类型值的名字添加前缀。

//bad public enum ImageMode { ImageModeBitmap, ImageModeGrayScale, ImageModeRgb, } //good public enum ImageMode { Bitmap, GrayScale, Rgb, }

枚举的规范挺多的,但即使不特别提出来,参考.NET Framework中的枚举也能很好地遵守这些规范。

2.4 集合

不要在公共API中使用ArrayList或List。
不要在公共API中使用Hashtable或Dictionary<TKey,Tvalue>。

这些类型的设计目的是为了用于内部实现,应该使用Collection、IEnumerable、或IDictionary<TKey,Tvalue>。

在公共API中优先使用集合,避免使用数组。
不要提供可设置的集合属性。
用Collection或其子类--如果属性或返回值表示可读写的集合。
用ReadOnlyCollection或其子类,在少数情况下用IEnumerable,如果属性或返回值表示只读的属性。

总的来说就是不要让集合被人不明不白地修改了。现在我在处理的遗留代码既使用数组作为属性,又可Get和Set,毕竟是从很久以前一路修改过来的,当时的开发者应该也没想到这些代码现在会让人这么困扰吧。

用描述集合中项目短语的复数形式来命名集合属性,而不要使用短语的单数形式加“List”或“Collection”后缀。

例如,要用Items、Objects,而不用ItemList、ObjectCollection。

2.5 异常

不要在框架代码中捕获System.Exception或System.SystemException,除非打算重新抛出。
不要在框架的代码捕获具体类型不确定的异常(比如System.Exception、System.SystemException,等等)时,把错误吞了。

总之不要捕获System.Exception和System.SystemException,要让用户知道哪里发生了问题。无论是不是框架的代码,把异常吞了的做法都很让人困扰,除非有充分的理由。

不要正常的控制流中使用异常,如果能够避免的话。

很常见到捕获了System.Exception做跳转分支,以及明明有TryParse却还是用TryCatch的代码。

在捕获并重新抛出异常时使用空的throw语句。这是保持异常调用栈不变的最好方法。

总有人喜欢把异常封装一下,然后就把异常类型改变,StackTrace或InnerException弄丢。

不要抛出System.Exception与System.SystemException。

2.6 事件

用受保护的虚方法来触发事件。
让触发事件的受保护的方法带一个参数,该参数的类型为事件参数类,该参数的名字应该为e。

public event EventHandler ContentRendered; protected virtual void OnContentRendered(EventArgs e);

上面是WPF中Window类的代码,WPF的各个控件都有很好地执行这个规范,但自定义控件及其它控件库则不是。

用object作为事件处理函数的第一个参数的类型,并将其命名为sender。
用System.EventArgs或其子类作为事件处理函数的第二个参数的类型,并将其命名为e。

同样是DataContextChanged事件,WPF有遵循规范,但UWP则不然。我可以理解只有FrameworkElement会触发DataContenxtChanged事件所以用FrameworkElement作为sender的类型,但将这个理论延伸到所有事件显然不合适,到底UWP是怎么回事?

//WPF private void MainWindow_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { throw new NotImplementedException(); } //UWP private void MainPage_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args) { throw new NotImplementedException(); }

用动词或动词短语来命名时间。
这样的例子包括Clicked、Painting、DroppedDown,等等。
用现在时和过去时来赋予事件名以之前和之后的概念。
例如,在窗口关闭之前发生的close事件应该命名为Closing,而在窗口关闭之后发生的应该命名为Closed。

所以WPF中Button的Click事件一直让我很困扰,Xamarin改为Clicked就好多了。

还有一点比较困扰的是事件处理函数的命名,常常见到同一个类存在以下命名方式:

Loaded += OnLoaded; _inlineBackButton.Click += OnInlineBackButtonClicked; SizeChanged += MasterDetailsView_SizeChanged;

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

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