随笔分类 -  编写高质量代码改善C#程序的157个建议

摘要:建议116:避免用非对称算法加密文件 MD5值或者说HASH值是一种不可逆的算法。如果需要从密文还原成明文,那么就需要对称和非对称这两类可逆算法了。 对称算法示意图: 在对称算法中,首先需要发送方和接收方协定一个密钥K。K可以是一个密钥对,但必须是加密密钥和解密密钥之间能相互推算出来的。在最简单也是 阅读全文
posted @ 2017-12-08 16:24 指间的徘徊 阅读(324) 评论(0) 推荐(0) 编辑
摘要:建议115:通过HASH来验证文件是否被篡改 MD5算法作为一种最通用的HASH算法,也被广泛用于文件完整性的验证上。文件通过MD5-HASH算法求值,总能得到一个固定长度的MD5值。虽说MD5是一种压缩算法,以致可能存在多个样本空间会得到相同目标字符串的情况,但是这种概率很小。一个1GB的文件,哪 阅读全文
posted @ 2017-12-08 16:22 指间的徘徊 阅读(435) 评论(0) 推荐(0) 编辑
摘要:建议114:MD5不再安全 MD5不再安全不是就算法本身而言的。如果从可逆性的角度出发,MD5值不存在被破解的可能性。 MD5被广泛应用于密码验证和消息完整性验证。假设新注册一个用户,当注册用户的密码第一次被存储到数据库时,往往会将其转换为MD5值存储: 输出为: 保存密码原文:liming's k 阅读全文
posted @ 2017-12-08 16:20 指间的徘徊 阅读(308) 评论(0) 推荐(0) 编辑
摘要:建议113:声明变量前考虑最大值 假设正在开发一个工资系统,其中一个模块负责处理加薪。代码如下: 输出的结果是: 第一次加薪,工资总数:65535第二次加薪,工资总数:0工资被清零了。 如果让一个刚入行的程序员来写工资系统,他可能会给我们设计一个ushort字段来存储月薪。65535元?够多了,谁的 阅读全文
posted @ 2017-12-08 16:16 指间的徘徊 阅读(247) 评论(0) 推荐(0) 编辑
摘要:建议112:将现实世界中的对象抽象为类,将可复用对象圈起来就是命名空间 在我们身边的世界中,对象是什么?对象就是事物,俗称“东西”。那么,什么东西算得上是一个对象呢?对象有属性、有行为。以动物为例,比如猫(Cat)。Cat可以有Name,这就是属性;Cat有一个恶习ScratchSofa(挠沙发), 阅读全文
posted @ 2017-12-08 15:46 指间的徘徊 阅读(245) 评论(0) 推荐(0) 编辑
摘要:建议111:避免双向耦合 双向耦合是指两个类型之间相互引用。下面的代码是一种典型的双向耦合: 双向耦合在同一项目下,不会存在太多的问题,带来的只是设计问题。不过,如果两个类在不同的项目中时,就必须考虑解耦了,因为.NET不允许项目之间相互引用。如果尝试两个项目相互引用将出现错误提示。 常见的解耦方式 阅读全文
posted @ 2017-12-07 18:02 指间的徘徊 阅读(275) 评论(0) 推荐(0) 编辑
摘要:建议110:用类来代替enum 枚举(enum)用来表示一组固定的值。例如,为了表示星期信息,我们可以定义枚举Week: 枚举最大的优点在于它的类型是值类型。相比较引用类型来说,它可以在关键算法中提升性能,因为它不需要创建在“堆”中。但是,如果不考虑这方面的因素,我们不妨让类(引用类型)来代替枚举。 阅读全文
posted @ 2017-12-07 18:00 指间的徘徊 阅读(305) 评论(0) 推荐(0) 编辑
摘要:建议109:谨慎使用嵌套类 使用嵌套类的原则是:当某类型需要访问另一个类型的私有成员时,才将它实现为嵌套类。一个典型的例子是在实现集合时,要为集合实现迭代器,这时用到了嵌套类。代码如下所示: 我们可以注意到,嵌套类ArrayListEnumeratorSimple访问了若干外部类ArrayList的 阅读全文
posted @ 2017-12-07 17:57 指间的徘徊 阅读(205) 评论(0) 推荐(0) 编辑
摘要:建议108:将类型标识为sealed sealed能够阻止类型被其他类型继承。代码如下: 这段代码提示: “无法从密封类型SampleClass派生。” 将类型修饰为sealed能够有效控制继承的深度。一个类型如果确信没有必要被继承,应该及时将其变为密封类。 在密封类中声明protected方法也是 阅读全文
posted @ 2017-12-07 17:53 指间的徘徊 阅读(202) 评论(0) 推荐(0) 编辑
摘要:建议107:区分静态类和单例 有一种观点认为:静态类可以作为单件模式的一种实现方式。事实上,这是不妥当的。按照传统的观点来看,单例是一个实例对象。而静态类并不满足这一点。静态类也直接违反面向对象三大特性的两项:继承和多态。 无法让一个静态类从其它类型继承的实例如下: 上面代码编译直接通不过。同时,已 阅读全文
posted @ 2017-12-07 17:51 指间的徘徊 阅读(270) 评论(0) 推荐(0) 编辑
摘要:建议106:为静态类添加静态构造函数 静态类可以拥有构造方法,这就是静态构造方法。静态构造方法与实例构造方法比较有几个自己的特点: 只被执行一次,且在第一次调用类成员之前被运行时执行。 代码无法调用它,不像实例构造方法使用new关键字就可以被执行。 没有访问标识符。 不能带任何参数。 使用静态构造方 阅读全文
posted @ 2017-12-07 17:49 指间的徘徊 阅读(213) 评论(0) 推荐(0) 编辑
摘要:建议104:用多态代替条件语句 假设要开发一个自动驾驶系统。在设计之初,此自动驾驶系统拥有一个驾驶系统命令的枚举类型: 当前该枚举存在两个命令:开始、停止。又假设有一个驾驶方法可以处理车辆接收到的指令。一开始我们可能像下面这样编码: 有些人可能喜欢用switch语句(当然,switch本质上也是if 阅读全文
posted @ 2017-12-07 17:33 指间的徘徊 阅读(366) 评论(0) 推荐(0) 编辑
摘要:建议103:区分组合和继承的应用场合 继承所带来的多态性虽然是面向对象的一个重要特性,但这种特性不能在所有的场合中滥用。继承应该被当做设计架构的有用补充,而不是全部。 组合不能用于多态,但组合使用的频率却要远远高于继承。 继承UML图如下: 对应的代码如下: 组合UML图如下: 对应代码如下: 从设 阅读全文
posted @ 2017-12-07 17:30 指间的徘徊 阅读(308) 评论(0) 推荐(0) 编辑
摘要:建议102:区分接口和抽象类的应用场合 接口和抽象类有一些显而易见的区别: 这些区别导致两者的应用场景不同: 从某种角度来看,抽象类比接口更具备代码的重用性。子类无须编写代码即可具备一个共性的行为。 采用抽象类的另一个好处是,如果为为基类增加一个方法,则继承该基类的所有子类自然就会具备这个额外的方法 阅读全文
posted @ 2017-12-07 17:29 指间的徘徊 阅读(248) 评论(0) 推荐(0) 编辑
摘要:建议101:使用扩展方法,向现有类型“添加”方法 考虑如何让一个sealed类型具备新的行为。以往我们会创建一个包装器类,然后为其添加方法,而这看上去一点儿也不优雅。我们也许会考虑修改设计,直接修改sealed类型,然后为其发布一个新的版本,但这依赖于你拥有全部的源码。更多的时候,我们会采取针对第三 阅读全文
posted @ 2017-12-07 17:28 指间的徘徊 阅读(254) 评论(0) 推荐(0) 编辑
摘要:建议100:静态方法和实例方法没有区别 静态方法在加载时机和内存使用上和实例方法完全一致。在这里,我们先引出一个概念“类型对象”。比如类型Person,我们都知道new Person() 会产生一个对象,这个对象叫做“实例对象”,它在运行时会加载到GC Heap上。而“类型对象”是指代表Person 阅读全文
posted @ 2017-12-07 15:48 指间的徘徊 阅读(324) 评论(0) 推荐(0) 编辑
摘要:建议99:重写时不应使用子类参数 重写时,如果使用了子类参数,可能会偏离设计者的预期目标。比如,存在一个如下继承体系: 现在,类型ManagerSalary中的SetSalary方法重写了Salary中的相同方法,重写的方法采用一个子类参数: 调用者的代码看起来如下: 设计者的本意是要设置经理的薪水 阅读全文
posted @ 2017-12-07 15:43 指间的徘徊 阅读(207) 评论(0) 推荐(0) 编辑
摘要:建议98:用params减少重复参数 如果方法的参数数目不定,且参数类型一致,则可以使用params关键字减少重复参数声明。 此处三个方法可以合并成一个方法: 转自:《编写高质量代码改善C#程序的157个建议》陆敏技 阅读全文
posted @ 2017-12-07 15:42 指间的徘徊 阅读(233) 评论(0) 推荐(0) 编辑
摘要:建议97:优先考虑将基类型或接口作为参数传递 除了公开及类型或接口外,方法的参数也应该考虑基类型或接口。 以Enumerable类型为例,它的成员方法中只要涉及需要操作集合对象的地方,都要使用IEnumerable泛型接口,比如: 该方法用于获取集合指定数量的一个子集。正是因为存在这个扩展方法。我们 阅读全文
posted @ 2017-12-07 15:41 指间的徘徊 阅读(237) 评论(0) 推荐(0) 编辑
摘要:建议96:成员应优先考虑公开基类型或接口 类型成员如果优先考虑公开及类型或接口,那么会让类型支持更多的应用场合。 FCL中最典型的例子是集合的功能操作。集合根据功能划分有多种类型,比如List<T>、Dictionary<TKey,TValue>、HashSet<T>等。以一个最简单的操作Empty 阅读全文
posted @ 2017-12-07 15:40 指间的徘徊 阅读(190) 评论(0) 推荐(0) 编辑