首页 > 学院 > 开发设计 > 正文

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

2019-11-17 03:09:36
字体:
来源:转载
供稿:网友

改善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条建议.


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表