编写高质量代码改善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; 

 

posted @ 2014-03-28 10:33  aehyok  阅读(5090)  评论(24编辑  收藏  举报