改善C#程序的157个建议(2)

4. TryParse比Parse好

1)TryParse,Parse比较两者的异同
相同点:两者都可以将字符串转型为本身的类型。
不同点:如果字符串不满足转换要求。parse方法会引发一个异常,TryParse方法则不会引发异常,它会返回false,同时将result置为0
引发异常这个过程会对性能造成损耗,所以TryParse比Parse好。
2)例如:

			double re;
            long ticks;

            //double.Parse 运行成功的情况
            Stopwatch sw = Stopwatch.StartNew();
            for(int i = 0; i < 1000; i++) {
                try {
                    re = double.Parse("123");
                } catch {
                    re = 0;
                }
            }
            sw.Stop();
            ticks = sw.ElapsedTicks;
            Console.WriteLine("double.Parse()成功,{0}ticks", ticks);

            //double.TryParse 运行成功的情况
            sw = Stopwatch.StartNew();
            for (int i = 0; i < 1000; i++) {
                if (double.TryParse("123", out re)==false) {
                    re = 0;
                }
            }
            sw.Stop();
            ticks = sw.ElapsedTicks;
            Console.WriteLine("double.TryParse()成功,{0}ticks", ticks);


            //double.Parse 运行失败的情况
            sw = Stopwatch.StartNew();
            for (int i = 0; i < 1000; i++) {
                try {
                    re = double.Parse("abc");
                } catch {
                    re = 0;
                }
            }
            sw.Stop();
            ticks = sw.ElapsedTicks;
            Console.WriteLine("double.Parse()失败,{0}ticks", ticks);

            //double.TryParse 运行失败的情况
            sw = Stopwatch.StartNew();
            for (int i = 0; i < 1000; i++) {
                if (double.TryParse("abc", out re) == false) {
                    re = 0;
                }
            }
            sw.Stop();
            ticks = sw.ElapsedTicks;
            Console.WriteLine("double.TryParse()失败,{0}ticks", ticks);
            Console.ReadKey();

运行结果:
在这里插入图片描述
由此可见:
Tryparse和Parse如果执行成功,他们的效率在一个数量级上,甚至在本例循环内,TryParse所带来的效率比Parse还高一些。
如果执行失败,Parse的执行效率远远低于TryPase。

5. 使用int?来确保值类型也可以为null

1)基元类型为什么需要为null?考虑以下两个场景:

  • 数据库中一个int字段可以被置为null,在C#中,值被取出来后,为了将他赋值给int类型,不得不手下判断一下他是否为null。如果将null值直接赋值给int类型会引发一场。
  • 在一个分布式系统中,服务器需要接受并解析来自客户端的数据。一个int型数据可能在传输过程中丢失或被篡改了,转型失败后应该保存为null,而不是提供一个初始值。

2)Nullable是什么?
它是一个结构体,表示可为空的类型。
它可以简写为int?

3)可空类型与对应基元类型的相互转换

           //基元类型提供了其对应可空类型的隐式转换
            int? i = null;
            int j = 0;
            i = j;
            Console.WriteLine("i={0},j={1}", i, j);

            //可控类型不可隐式转换为对应的基元类型
            int? ii = 123;
            int jj;
            //jj = ii;//不可以将一个可空类型隐式转换为对应的基元类型。
            //正确的转换形式:
            if(ii.HasValue) {//HasValue是用来判断,此参数是否有除了null以外的值;只有【数据类型?】才有HasValue属性
                jj = ii.Value;
            } else {
                jj = 0;
            }
            Console.WriteLine("i={0},j={1}", i, j);
            Console.ReadKey();

6. 区别readonly和const的用法

1)readonly与const的区别?

  • const是一个编译器常量,readonly是一个运行时常量
  • const只能修饰基元类型(对应引用类型的常熟,可能的值只能说string,null),而readonly没有限制。
  • const默认就是静态的,而readonly如果设置为静态则需要显示声明。
  • const字段只能在该字段的声明中使用常量初始化。readonly字段可以在声明或构造函数中初始化。在构造函数内,可以多次对readonly字赋值。

7. 将0值作为枚举的默认值

允许使用的枚举类型有byte,sbyte,short,ushort,int,uint,long,ulong。应该始终将0值作为枚举类型的默认值。
例如:
一个代表星期的枚举类Week

            enum Week { 
            Monday=1,
            Tuesday=2,
            Wednesday=3,
            Thursday=4,
            Friday=5,
            Saturday=6,
            Sunday=7
        }
        static Week week;
        static void Main(string[] args) {
            Console.WriteLine(week);
            Console.ReadKey();
        }

输出结果:0
Week看上去多了第8个值,而且这段代码没有异常。所以,应该始终为枚举的0值指定默认值。比如在上面的枚举类型Week中,可以将显示为元素赋值去掉,编译器会自动从0值开始技术,然后逐个为元素的值+1

8. 避免给枚举类型的元素提供显示的值。

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

enum Week { 
            Monday=1,
            Tuesday=2,
            ValueTemp,
            Wednesday=3,
            Thursday=4,
            Friday=5,
            Saturday=6,
            Sunday=7
        }
        static void Main(string[] args) {
            Week week = Week.ValueTemp;
            Console.WriteLine(week);//Wednesday
            Console.WriteLine(week==Week.Wednesday);//true
            Console.ReadKey();
        }

很显然这不是我们想要的结果。
为了避免不必要的错误,尽量避免给枚举类型的元素提供显示的值。

9. 习惯重载运算符。

在构建自己的类型时,我们应该始终考虑是否可以用于运算符重载。
例如:

    class Program
    {
        static void Main(string[] args) {
            Salary s1 = new Salary() { RMB = 22 };
            Salary s2 = new Salary() { RMB = 33 };
            Salary sum = s1 + s2;
            Console.WriteLine(sum.RMB);//55
            Console.ReadKey();
        }
    }
    class Salary
    {
        public int RMB { get; set; }
        public static Salary operator + (Salary s1,Salary s2) {
            s2.RMB += s1.RMB;
            return s2;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值