本文摘自PHP中文网,作者php是最好的语言,侵删。
建议1:正确使用字符串string
1 2 | string str 1 = "str1" + 9 ;
string str 2 = "str2" + 9 .ToString();
|
第一行代码会产生一次装箱,还有一次string的concat
而第二行代码使用ToString(),内部使用的是Number.FormatInt32
其原型为

而NumberFormatInt32是一个非托管方法,运行效率比正常c#的托管代码要高很多,所以第二行代码的效率比第一行高
至于什么是托管代码非托管代码,我引用了其他博客的一段话:
托管代码与非托管代码众所周知,我们正常编程所用的高级语言,是无法被计算机识别的。需要先将高级语言翻译为机器语言,才能被机器理解和运行。
在标准C/C++中,编译过程是这样的:

源代码首先经过预处理器,对头文件以及宏进行解析,然后经过编译器,生成汇编代码,接着,经过汇编,生成机器指令,最后将所有文件连接起来。
这种编译方式的优点在于,最终直接生成了机器码,可以直接被计算机识别和运行,无需任何中间运行环境,但缺点也在于,由于不同平台能够识别的机器码不同,因此程序的跨平台能力较差。
而在Java语言中,源代码并没有被直接翻译成机器码,而是编译成了一种中间代码(字节码Bytecode)。因此,运行Java程序需要一个额外的JRE(Java Runtime Enviromental)运行环境,在JRE中存在着JVM(Java Virtual Mechinal,Java虚拟机),在程序运行的时候,会将中间代码进一步解释为机器码,并在机器上运行。
使用中间代码的好处在于,程序的跨平台性比较好,一次编译,可以在不同的设备上运行。
托管/非托管是微软的.net framework中特有的概念,其中,非托管代码也叫本地(native)代码。与Java中的机制类似,也是先将源代码编译成中间代码(MSIL,Microsoft Intermediate Language),然后再由.net中的CLR将中间代码编译成机器代码。
而C#与Java的区别在于,Java是先编译后解释,C#是两次编译。
托管的方式除了拥有跨平台的优点之外,对程序的性能也产生一定的影响。但程序性能不在本文讨论的范围,这里不在赘述。
此外,在.net中,C++也可以进行托管扩展,从而使C++代码也依赖于.net和CLR运行,获得托管代码的优势。 |
简单理解就是托管代码加了一个中间层,使其可以跨平台,不过效率会降低,而非托管代码就不会产生这样的情况
所以我们编写代码秉承一个原则:尽量减少装箱拆箱
StringBuilder
StringBuilder的效率来源于预先以非托管的方式分配内存,如果没有预先定义长度,默认长度为16,不够的时候会重新分配内存,依次加16的倍数,所以如果你提前知道字符串需要的最大长度,最好预先定义好,这样就不会频繁分配内存从而带来效率的降低
2、使用默认转型方法
这个建议的大体内容是尽量使用系统所带的转换类型的方法
例如 int.Parse ToString() System.Convert 等等
3、区别对待强转类型和as is
两个类型之间转换有两种情况
1. 他们是父子类的关系: ChildType = (ChildType)ParentType
2.没有继承关系,或者继承同一个父类,这时候就需要重写强转方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class FirstType
{
public string Name { get; set; }
}
class SecondType
{
public string Name { get; set; }
public static explicit operator SecondType(FirstType firstType)
{
SecondType secondType = new SecondType() { Name = firstType.Name };
return secondType;
}
}
FirstType firstType = new FirstType() { Name = "张" };
SecondType secondType = (SecondType)firstType;
|
如果是继承的关系,为了效率推荐使用 ChildType = ParentType as ChildType
这个就更上面提到的,尽量使用系统方法的转换,而不是强制转换
我写Unity的时候有这样一个需求,右键点击装备的时候会使用,装备有Equipment,Weapon,我们需要判断是Equipment还是Weapon类型,它们都是继承Item类型,有两种方法可用:
1 2 3 4 5 6 7 8 9 10 11 | Weapon weapon = item as Weapon;
if(weapon != null)
{
//TODO 使用武器
}
if(item is Weapon)
{
weapon weapon = item as Weapon;
//TODO 使用武器
}
|
第一种方法只判断了一次类型,而第二种方法判断了两次类型
书上说as不能判断基元类型,但是经过我的测试发现书上写错了,as仅仅不能判断值类型,这里大家可以自己测试一下


相关文章:
C#学习记录:编写高质量代码改善整理建议4-8
C#学习记录:编写高质量代码改善整理建议9-15
以上就是C#学习记录:编写高质量代码改善整理建议1-3的详细内容!
相关阅读 >>
C# gridcontrol的模糊查询实现代码实例
C# 清除html标签标记
关于C#中三个关键字params,ref,out的详细介绍
C#单位转换器的图文代码详细介绍
详细概述C#中的常用字符串方法
C#开发实例-订制屏幕截图工具(一)功能概览(图)
具体介绍C#使用selenium+phantomjs抓取数据的案例(图文)
unity3d用什么语言开发?
C#学习记录:编写高质量代码改善整理建议1-3
具体介绍C#编程获取ip地址的方法
更多相关阅读请进入《C#》频道 >>
清华大学出版社
作者:[美]克里斯琴·内格尔(Christian Nagel)著。出版时间:2019年3月。
转载请注明出处:木庄网络博客 » C#学习记录:编写高质量代码改善整理建议1-3