当前位置: 首页 > news >正文

【进阶修炼】——改善C#程序质量(1)

    这是一个大纲形式的概要,以便自己可以花较少的时间反复阅读。在开发中,多加注意这些有用的建议,让自己成为一个更优秀的程序员。内容主要来自《编写高质量代码-改善C#程序的157个建议》(陆敏技),这本书写的真的很好,都是些实战经验的总结,建议大家购买,这其中的建议不仅仅适合于C#,只要你做.NET开发,阅读此书都会从中受益。同时,其他书籍和资料的一些好的编程建议,我也会不断更新到这里。

1, 字符串使用。

应避免发生装箱;避免分配额外的内存;考虑使用StringBuilder来替代string。string.Format内部使用了StringBuilder,比较高效。

2, 类型转换。

主要这几方面,基元类型(int32,double,string,object等)之间的转换包括隐式转换和显示转化,自定义类型可以重载运算符实现隐式转换(implicit);类型本身提供了Prase和TryPrase,或ToDouble、ToDateTime等方法;帮助类如System.Convert实现基元类型之间的转换,System.BitConverter实现基元类型和数组之间的转换。父子类之间的显示和隐式转换。

3, As和Is。

尽量不要用Is判断后再强制转换的方式,直接用As运算符可以减少一次转型。

4, TryParse比Parse高效。

TryParse不会抛出异常,如果在循环中用Parse,频繁出现异常时会大大损害性能。

5, 使用int?确保值类型可以为null。

值类型可以隐式转换为可空值类型。判断可空类型是否包含值可以用HasValue方法测试,还可以用??运算符简化代码。

6, Readonly和const。

const是一个编译期常量,readonly是一个运行时常量。Const只能修饰基元类型、枚举类型和字符串类型;readonly可以修饰任何类型。Const天生就是static的,不用添加static修饰符。Readonly比const有更好的灵活性,但性能略有损失,比起这点性能损失,更推荐用readonly。

7, 将0值作为枚举类型的默认值。

枚举类型在声明时默认值是0,如果0值没有对应相应的枚举值将丧失业务意义。

8, 避免给枚举元素提供显示的值。

因为如何想在枚举的中间添加一个元素,不得不重新修改后面所有元素的值。这种情况有一个例外是应用了FlagAttribute的枚举,可以显示赋值。

9, 习惯重载运算符。

如果自己设计的类有加法意义,应该用operator关键字重载+运算符,使用户使用更加自然。

10, 创建对象时考虑是否实现比较器。

如果对象要用于排序,应该实现IComparable接口。如果想改变这种默认的排序策略,也可以自定义类实现ICompare接口,后者无需去改变类型的结构,而是添加一个新类来实现,更加灵活。

11, 区别对待==和Equals。

这两个运算符都可以被重载,但都应该保证这样的语义:对于值类型,如果类型的值相等,都应该返回true;对于引用类型,如果类型指向同一个对象,都应返回true。对于自定义的类型,如有必要,可以重写Equals方法保证值相等就返回true。但一般不重载==,使其保留引用相等性的判断。另外,要判断两个对象是否是同一个对象,可以用Object.ReferenceEquals方法。

12, 重写Equals时要重写GetHashCode。

这是因为一些基于散列值的集合,如Hashtable,Dictionary等,会用到Key的HashCode值来查找Value值。既然Equals的含义被重写了,那么HashCode也应该与其保持一致。

13, 为类型输出格式化字符串。

一种是让类型继承IFormatable接口,另一种是自定义格式化器,需要实现IFormatProvider和ICustomFormatter。后者的实现更加灵活。

14, 浅拷贝和深拷贝。

这两种拷贝都应继承ICloneable接口来实现。浅拷贝可以用this.MemberwiseClone方法。深拷贝可以用BinaryFormatter将对象序列化到MemoryStream后,再反序列化成对象。如果在一个类中要同时实现浅拷贝和深拷贝,可以添加DeepClone和ShadowClone两个方法加以区分。

15, 使用dynamic来简化反射的调用。

Dynamic是.net 4.0引入的一个新特性,编译器不会对dynamic类型的变量进行检查,我们可以在dynamic的变量上调用方法,检查属性值,而不必写繁琐的反射代码。Var关键字只是一个语法糖,编译器编译后会替换成具体的变量类型,而dynamic被编译后,会转换成object类型,对方法和属性等的调用C#内部本质还是用反射来做的,但这大大减轻了程序员的工作量。

使用dynamic来简化反射的调用。Dynamic是.net 4.0引入的一个新特性,编译器不会对dynamic类型的变量进行检查,我们可以在dynamic的变量上调用方法,检查属性值,而不必写繁琐的反射代码。Var关键字只是一个语法糖,编译器编译后会替换成具体的变量类型,而dynamic被编译后,会转换成object类型,对方法和属性等的调用C#内部本质还是用反射来做的,但这大大减轻了程序员的工作量。

转载于:https://www.cnblogs.com/xiashengwang/p/4013668.html

相关文章:

  • Ubuntu端口开放
  • 二叉树详解
  • Photoshop打造唯美的蓝色古装外景人物图片
  • ASP.NET-FineUI开发实践-6
  • HDU-2069-Coin Change
  • javaweb学习总结(三十)——EL函数库
  • Bandizip---解压缩工具(可替代RAR)
  • 阿里云服务器购买完整流程
  • ireport默认参数和变量的含义
  • js几种排序算法
  • 2014年spark开发者大赛火热进行中!
  • 网卡别别名设置
  • Ping过程详解
  • require和import
  • 统计二进制数中1的个数
  • download使用浅析
  • echarts的各种常用效果展示
  • ES6语法详解(一)
  • V4L2视频输入框架概述
  • vue-router 实现分析
  • yii2中session跨域名的问题
  • 关于Java中分层中遇到的一些问题
  • 缓存与缓冲
  • 回流、重绘及其优化
  • 排序算法之--选择排序
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 树莓派 - 使用须知
  • 数组大概知多少
  • 移动端 h5开发相关内容总结(三)
  • 原生Ajax
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • 《天龙八部3D》Unity技术方案揭秘
  • kubernetes资源对象--ingress
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • ​TypeScript都不会用,也敢说会前端?
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • (11)MATLAB PCA+SVM 人脸识别
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (pojstep1.3.1)1017(构造法模拟)
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (译) 理解 Elixir 中的宏 Macro, 第四部分:深入化
  • (原創) 人會胖會瘦,都是自我要求的結果 (日記)
  • .naturalWidth 和naturalHeight属性,
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .net 中viewstate的原理和使用
  • .NET分布式缓存Memcached从入门到实战
  • .NET微信公众号开发-2.0创建自定义菜单
  • /etc/fstab 只读无法修改的解决办法
  • ??javascript里的变量问题