改善C# 程序 的N个建议(1-5)

  最近有空了,还有本来想趁最近空闲时间深入学习一下java的,但是…(我还没能力去黑java,只能说我用不习惯,有点像用惯Windows 操作系统的人转用其他系统一样,会有些不习惯).而且很长一段时间没写C# 了,加上看到一本《编写高质量代码:改善C#程序的157个建议》还不错,我正好可以回顾一下C#,我是靠C# 入门程序员的.看家本领不能丢啊,所以有了写此系列文章的想法.一下就说多了,切入正题:

  建议1:对String 与值类型进行字符串拼接使用.ToString()在拼接.(string str=”str”+9.ToString())

string str1 = "str" + 9;

string str2 = "str" + 9.ToString();//better

例如上面这两段代码,第一行,需要装箱.第二行则不用装箱.证据如下:

L_0000: nop 

    L_0001: ldstr "str"

    L_0006: ldc.i4.s 9

    L_0008: box int32

    L_000d: call string [mscorlib]System.String::Concat(object, object)

    L_0012: stloc.0 

    L_0013: ldstr "str"

    L_0018: ldc.i4.s 9

    L_001a: stloc.3 

    L_001b: ldloca.s num

    L_001d: call instance string [mscorlib]System.Int32::ToString()

    L_0022: call string [mscorlib]System.String::Concat(string, string)

    L_0027: stloc.1

可以看到第四行,”box”指令.说明发生装箱操作.虽然只有一次装箱操作.对系统整体性能毫无影响.而L_001d 调用了System.Int32.ToString()通过IL中看是调用非托管代码,无法继续跟踪.但是我有代码洁癖,能”干净”点就干净点.

建议2:要清楚如何对自定义类型做类型转换(IP ip = (IP)"192.168.0.1") .

自定义一个IP类:

public class IP:IConvertible,IFormatProvider

        {

            IPAddress value;

            public IP(string ip)

            {

                IPAddress.TryParse(ip, out value);

            }

            public static implicit operator IP(string ip)

            {

                IP iptemp=new IP(ip);

                return iptemp;

            }



            public override string ToString()

            {

                return value.ToString();

            }

            //省略部分代码...

            public bool ToBoolean(IFormatProvider provider)

            {

                throw new InvalidCastException("IP-to-Boolean conversion is not supported.");

            }



            public string ToString(IFormatProvider provider)

            {

                return value.ToString();

            }

            //省略部分代码...



            public object GetFormat(Type formatType)

            {

                return null;

            }

        }

就可以这样调用:

IP ip = new IP ("192.168.0.1");

 ip = (IP)("192.168.0.2");

 bool boolIP = ip.ToBoolean(ip);

 bool boolIP2 = Convert.ToBoolean(ip);

隐式转换需要实现隐式操作符(implicit operator)的方法.如果要转换成基元类型就要实现IConvertible.

  建议3: 强制转型和as ,is 的用法

强制转型一般有两种情况:

1.两种类型依靠转换操作符完成彼此间的转型(如:隐式转换和Convert).

2.子类和父类之间的转型.

第一种情况,建议2 已经详细阐述过了.那个第二种情况应该怎么处理呢?

as ,is 就是C#语言设计师(Anders.Hejlsberg)针对第二种情况进行设计的关键字.

is:判断是否是继承关系(返回bool)

as: 提供父类向子类的转型.如果转型失败,也不会抛出 Exception ,只会返回null.

public static void FatherConvertToSun(Father father)

{

    if(father is sun)

    {   

        Sun sun = father as Sun;

        //省略部分代码....

    }

 }

建议4:基元类型之间的强制转型(值类型转为引用类型).

值类型都提供了Tryparse 和Parse 方法提供转型.测试代码如下:

public static void TestTryParse(string item)

        {

            double number = 0;

            Stopwatch sw = Stopwatch.StartNew();

            for (int i = 0; i < 1000; i++)

            {

                if (double.TryParse(item, out number) == true)

                {

                    number = 0;

                }

            }

            long time = sw.ElapsedTicks;

            if (double.TryParse(item, out number) == true)

            {

                Console.WriteLine(string.Format("TryParse成功耗时:{0}", time));

            }

            else

            {

                Console.WriteLine(string.Format("TryParse失败耗时:{0}", time));

            }



       }
public static void TestParse(string item)

        {

            Stopwatch sw = Stopwatch.StartNew();

            double number = 0;

            for (int i = 0; i < 1000; i++)

            {

                try

                {

                    number = double.Parse(item);

                }

                catch (Exception ex)

                {

                    number = 0;

                }

            }

            long time = sw.ElapsedTicks;

            if (number != 0)

            {

                Console.WriteLine(string.Format("Parse成功耗时:{0}", time));

            }

            else

            {

                Console.WriteLine(string.Format("Parse失败耗时:{0}", time));

            }

        }

结果如下:

QQ截图20140516220338

TyeParse的效率比Parse 的效率高得多,特别是转型失败的时候.建议:值类型与引用类型之间使用TryParse转型.

建议5:可空值类型的使用环境.

1.从数据库中读取数字可空型字段(decimal,int)时,使用可空类型可以防止把null赋值给值类型报异常.

2.从分布式系统中,服务器需要接收和解析客户端发来的数字型数据.这些数字型数据也很有可能为空.

Nullable<int> i=null;//声明赋值方式1;

int ? n=null;//声明赋值方式2;

int j=n?? 0;//如果n为空将0赋值给j,否则 j=i;

可空类型有一个属性(HasValue)可以判断可空类型是否为null.

 

今天就到这来,明天继续5条建议.

你可能感兴趣的:(C#)