Page 25
?一定请在向用户输出结果时,使用基于StringComparison.CurrentCulture的字符串操作。
?一定请在比较语言无关字符串(符号,等)时,使用非语言学的StringComparison.Ordinal或者
StringComparison.OrdinalIgnoreCase值,而不是基于CultureInfo.InvariantCulture的字符串操作。一般而言,不要使用基于StringComparison.InvariantCulture的字符串操作。一个例外是当你坚持其语言上有意义,而与具体文化无关的情况。
?一定请使用String.Equals的重载版本来测试2个字符串是否相等。比如,忽略大小写后,判断2个字符串是否相等,
if(str1.Equals(str2, StringComparison.OrdinalIgnoreCase))
If(str1.Equals(str2, StringComparison.OrdinalIgnoreCase))Then
?一定不要使用String.Compare或CompareTo的重载版本来检验返回值是否为0,来判断字符串是否相等。这2个函数是用于字符串排序,而非检查相等性。
?一定请在字符串比较时,以String.ToUpperInvariant函数使字符串规范化,而不用String.ToLowerInvariant。
3.7 数组和集合
?您应该在低层次函数中使用数组,来减少内存消耗,增强性能表现。对于公开接口,则偏向选择集合。
集合提供了对于其内容更多的控制权,可以随着时间改善,提高可用性。另外,不推荐在只读场景下使用数组,因为数组克隆的代价太高。
然而,如果您把熟练开发者作为目标,对于只读场景使用数组也是个不错的主意。数组的内存占用比较低,这减少了工作区,并因为运行时的优化能更快的访问数组元素。
? 2016 Microsoft Corporation. All rights reserved.
Page 26
?一定不要使用只读的数组字段。字段本身只读,不能被修改,但是其内部元素可以被修改。以下示例展示了使用只读数组字段的陷阱:
Bad:
publicstaticreadonlychar[] InvalidPathChars = { '\\\, '<', '>', '|'};
这允许调用者修改数组内的值:
InvalidPathChars[0] = 'A';
您可以使用一个只读集合(只要其元素也是不可变的),或者在返回之前进行数组克隆。然而,数组克隆的代价可能过高:
publicstatic ReadOnlyCollection
return Array.AsReadOnly(badChars); }
publicstaticchar[] GetInvalidPathChars() {
return(char[])badChars.Clone(); }
?您应该使用不规则数组来代替使用多维数组。一个不规则数组是指其元素本身也是一个数组。构成元素的数组可能有不同大小,这样相较于多维数组能减少一些数据集的空间浪费(例如,稀疏矩阵)。另外,CLR能够对不规则数组的索引操作进行优化,所以在某些情景下,具有更好的性能表现。
// 不规则数组
int[][] jaggedArray = {
newint[] {1,2,3,4}, newint[] {5,6,7}, newint[] {8}, newint[] {9} };
Dim jaggedArray AsInteger()() = NewInteger()() _ { _
NewInteger() {1, 2, 3, 4}, _
? 2016 Microsoft Corporation. All rights reserved.
Page 27
NewInteger() {5, 6, 7}, _ NewInteger() {8}, _ NewInteger() {9} _ }
// 多维数组
int [,] multiDimArray = {
{1,2,3,4}, {5,6,7,0}, {8,0,0,0}, {9,0,0,0} };
Dim multiDimArray(,)AsInteger = _ { _
{1, 2, 3, 4}, _ {5, 6, 7, 0}, _ {8, 0, 0, 0}, _ {9, 0, 0, 0} _ }
?一定请将代表了读/写集合的属性或返回值声明为 Collection
?您应该重新考虑对于ArrayList的使用,因为所有添加至其中的对象都被当做System.Object,当从ArrayList取回值时,这些对象都会拆箱,并返回其真实的值类型。所以我们推荐您使用定制类型的集合,而不是ArrayList。比如,.NET 在System.Collection.Specialized命名空间内为String提供了强类型集合StringCollection。
?您应该重新考虑对于Hashtable的使用。相反,您应该尝试其他字典类,例如StringDictionary,NameValueCollection,HybridCollection。除非Hashtable只存储少量值,最好不要使用Hashtable。
?您应该在实现集合类型时,为其实现IEnumerable接口,这样该集合便能用于LINQ to Objects。
? 2016 Microsoft Corporation. All rights reserved.
Page 28
?一定不要在同一个类型上同时实现IEnumerator
?一定不要返回数组或集合的null引用。空值数组或集合的含义在代码环境中很难被理解。比如,一个用户可能假定如下代码能够正常运行,所以应该返回一个空数组或集合,而不是null引用。
int[] arr = SomeOtherFunc(); foreach(int v in arr) { ... }
3.8 结构体
?一定请确保将所有实例数据设置为0值,false或者是null。当创建结构体数组时,这样能防止意外创建了无效实例。
?一定请为值类型实现IEquatable
3.8.1 结构体vs类
?一定不要定义结构体,除非其具有如下特性:
? 它在逻辑上代表了一个单值,类似于原始类型(例如,int、 double,等等)。 ? 其示例大小小于16字节。 ? 它是不可变的。
? 它不会引发频繁的装箱拆箱操作。
? 2016 Microsoft Corporation. All rights reserved.