原文:编写高质量代码改善C#程序的157个建议[4-9]
前言
本文首先亦同步到http://www.cnblogs.com/aehyok/p/3624579.html。本文主要来学习记录一下内容:
建议4、TryParse比Parse好
建议5、使用int?来确保值类型也可以为null
建议6、区别readonly和const的使用方法
建议7、将0值设为枚举的默认值
建议8、避免给枚举类型的元素提供显式的值
建议9、习惯重载运算符
建议4、TryParse比Parse好
如果注意观察,除string之外的所有的基元类型。会发现它们都有两个将字符串转换为自身类型的方法:Parse和TryParse。以类型double为例。
两者最大的区别是,如果字符串格式不满足转换的要求,Parse方法将会引发一个异常;TryParse方法则不会引发异常,它会返回false,同时将result置为0。
//Parse int a = int.Parse("123a"); //TryParse int x = 0; if (int.TryParse("12a3", out x)) { //转换成功,x=123 } else { //转换失败,x=0 }
Parse转换失败会运行时报错
而TryParse转换失败返回false,将其赋值为0
TryParse和Parse两者都执行成功,那么TryParse的性能要比Parse性能稍微好一点,但是如果抛出异常,那么TryParse的性能比Parse提升了不少额。
不过这里并不建议为所有的类型都提供TryParse模式,只有在考虑到Parse会带来明显的性能损耗时,才建议使用TryParse。
建议5、使用int?来确保值类型也可以为null
基元类型为什么需要为null?需要考虑以下两个场景:
1、数据库中一个int字段可以被设置为null。在C#中,值被取出来后,为了将它赋值给int类型,不得不首先判断一下它是否为null。如果将null直接赋值给int类型,会引发异常。
2、在一个分布式系统中,服务器需要接收并解析来自客户端的数据。一个int型数据在传输的过程中可能会丢失或者被篡改。转型失败后应该保存为null值,而不是提供一个默认值。
类似的场景还有很多,在这里不进行更详尽的列举。在.NET2.0开始,便提供了一个额外的类型:可以为空的类型Nullable<T>。
通过定义可以发现,它是一个结构体。因为是结构体,所以只有值类型才可以作为“可以为空的类型”(引用类型本身可以为null)。一个可以为空的int类型可以表示为
Nullable<int> intA = null;
它也可以表示为
int? intA = null;
当然之后可以这样进行应用
int? i=123; int j = i ?? 0;
建议6、区别readonly和const的使用方法
关于两者的使用我之前也有专门介绍过,在这里就一笔带过:http://www.cnblogs.com/aehyok/p/3529079.html。
建议7、将0值设为枚举的默认值
允许使用的枚举类型有byte、sbyte、short、ushort、int、uint、long、ulong、应该始终将0值作为枚举的默认值。接下来我们通过示例来说明问题
enum Week { Money = 1, Tuesday = 2, Wednesday = 3, Thursday = 4, Friday = 5, Saturday = 6, Sunday = 7 }
在调用的时候发现
结果竟然出来了一个0,让人感觉怎么是第八个值出现了。所以建议将0设置为枚举的默认值。
建议8、避免给枚举类型的元素提供显式的值
一般情况下,没有必要给枚举类型的元素提供显式的值。创建枚举的理由之一,就是为了代替使用实际的值。不正确的为枚举类型的元素设定显式的值,会带来意想不到的错误。
enum Week { Money = 1, Tuesday = 2, TempValue, Wednesday = 3, Thursday = 4, Friday = 5, Saturday = 6, Sunday = 7 }
假如我们在如上枚举中,又添加了一个TempValue的元素。可以先猜测一下此时TempValue的值会是多少?
通过调试可以发现。当编译器发现元素ValueTemp的时候,它会自动在Tuesday=2的基础上+1,所以ValueTemp的值和Wednesday的值都是3。可见,枚举元素允许设定重复的值。
注意: 本建议也有例外的情况。例如,当为一个枚举类型指定System.FlagsAttribute属性就意味着可以为这些值执行And、Or、Not、Xor按位运算了,这样一来,枚举的每个元素的值就要求都是2的若干次幂,指数依次递增。
[Flags] enum Week { None = 0x0, Money = 0x1, Tuesday = 0x2, Wednesday = 0x4, Thursday = 0x8, Friday = 0x10, Saturday = 0x20, Sunday = 0x40 }
按位运算在这里不多说了,详情可以查看 http://www.cnblogs.com/NetBelieve/archive/2012/07/30/2615006.html
建议9、习惯重载运算符
在开发的过程中,应该习惯于使用微软提供给我们的语法特性。我想大部分人应该喜欢看到这样的语法特性:
int x = 7; int y = 8; int total = x + y;
而不是看到下面的语法:
int x = 7; int y = 8; int total = int.Add(x, y);
所以我们在自定义类型的时候,也可以考虑看看类型是否可以使用运算符重载。
public class Salary { public int RMB { get; set; } public static Salary operator +(Salary s1, Salary s2) { s2.RMB += s1.RMB; return s2; } }
那现在我们来进行调用的时候就方便了很多。
Salary s1 = new Salary() { RMB = 10 }; Salary s2 = new Salary() { RMB = 20 }; Salary s3 = s1 + s2;