欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]

程序员文章站 2022-03-21 17:33:32
建议4、TryParse比Parse好 如果注意观察,除string之外的所有的基元类型。会发现它们都有两个将字符串转换为自身类型的方法:Parse和TryParse。以类型double为例。 两者最大的区别是,如果字符串格式不满足转换的要求,Parse方法将会引发一个异常;TryParse方法则不 ......

  如果注意观察,除string之外的所有的基元类型。会发现它们都有两个将字符串转换为自身类型的方法:parse和tryparse。以类型double为例。

C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]

两者最大的区别是,如果字符串格式不满足转换的要求,parse方法将会引发一个异常;tryparse方法则不会引发异常,它会返回false,同时将result置为0。

C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]
//parse
int a = int.parse("123a");      
 
 //tryparse
int x = 0;
if (int.tryparse("12a3", out x))
{
  //转换成功,x=123
}
else
{
  //转换失败,x=0
}
C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]

parse转换失败会运行时报错

C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]

而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>。

C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]

通过定义可以发现,它是一个结构体。因为是结构体,所以只有值类型才可以作为“可以为空的类型”(引用类型本身可以为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值作为枚举的默认值。接下来我们通过示例来说明问题

C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]
   enum week
    {
        money = 1,
        tuesday = 2,
        wednesday = 3,
        thursday = 4,
        friday = 5,
        saturday = 6,
        sunday = 7
    }
C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]

在调用的时候发现

C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]

结果竟然出来了一个0,让人感觉怎么是第八个值出现了。所以建议将0设置为枚举的默认值。

建议8、避免给枚举类型的元素提供显式的值

 一般情况下,没有必要给枚举类型的元素提供显式的值。创建枚举的理由之一,就是为了代替使用实际的值。不正确的为枚举类型的元素设定显式的值,会带来意想不到的错误。

C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]
 enum week
    {
        money = 1,
        tuesday = 2,
        tempvalue,
        wednesday = 3,
        thursday = 4,
        friday = 5,
        saturday = 6,
        sunday = 7
    }
C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]

假如我们在如上枚举中,又添加了一个tempvalue的元素。可以先猜测一下此时tempvalue的值会是多少?

C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]

通过调试可以发现。当编译器发现元素valuetemp的时候,它会自动在tuesday=2的基础上+1,所以valuetemp的值和wednesday的值都是3。可见,枚举元素允许设定重复的值。

注意: 本建议也有例外的情况。例如,当为一个枚举类型指定system.flagsattribute属性就意味着可以为这些值执行and、or、not、xor按位运算了,这样一来,枚举的每个元素的值就要求都是2的若干次幂,指数依次递增。

C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]
[flags]
    enum week
    {
        none = 0x0,
        money = 0x1,
        tuesday = 0x2,
        wednesday = 0x4,
        thursday = 0x8,
        friday = 0x10,
        saturday = 0x20,
        sunday = 0x40
    }
C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]

按位运算在这里不多说了,详情可以查看 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);

所以我们在自定义类型的时候,也可以考虑看看类型是否可以使用运算符重载。

C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]
    public class salary
    {
        public int rmb { get; set; }
        public static salary operator +(salary s1, salary s2)
        {
            s2.rmb += s1.rmb;
            return s2;
        }
    }
C#程序编写高质量代码改善的157个建议【4-9】[TryParse比Parse、使用int?来确保值类型也可以为null、readonly和const、0值设为枚举的默认值、避免给枚举类型的元素提供显式的值、习惯重载运算符]

那现在我们来进行调用的时候就方便了很多。

            salary s1 = new salary() { rmb = 10 };
            salary s2 = new salary() { rmb = 20 };
            salary s3 = s1 + s2;