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

32, 总是优先考虑泛型。

泛型代码有很好的重复利用性,和类型安全性。

33, 应尽量避免在泛型类中声明静态成员。

静态成员达不到共享的目的。List<int>和List<String>是两个不同的类型,而静态成员是针对类型的。当然2个List<int>之间是可以共享静态成员的,但为了不必要的混淆,应该避免使用静态成员。

34, 为泛型参数添加约束。

没有约束的参数,功能是有限的,添加了约束后,我们就可以使用约束类型的方法和属性了,程序更加灵活。

35, 使用Default关键字为泛型变量指定默认值。

由于泛型变量可能是值类型,也可能是引用类型,不能为其赋值为null或0。

36, 尽量使用FCL中定义的委托声明。

Action,Func,Predicate这几个委托都有其泛型版本,基本都可以满足我们的需求,如没有特殊业务需要,应避免自己定义不必要的委托声明。.net中还有一些自带的委托,如:EventHander,EventHander<EventArg>,ThreadStart,ParameterizedThreadStart,AsyncCallback等,在确定系统没有提供我们所需的委托时,才考虑自定义委托。

37, 用Lambda表达式替代方法和匿名方法。

这里主要指方法参数为委托的时候。

38, 小心闭包的陷阱。

Lambda表达式会捕获局部变量,编译器会将这个局部变量放入一个闭包对象中。Lambda表达式执行时才会从这个闭包对象中去取实际的值。如果这个局部变量的值中途发生了改变,我们得到的结果就是最后改变的值,这可能和我们预想的值有些出入。

39, 了解委托的实质。

委托是一个方法指针。委托是一个类,对其进行实例化的时候,要将引用方法作为它的构造方法的参数。

40, 用event关键字为委托施加保护。

委托变量可以被恶意赋值为null。加了event关键字之后,在编译期就会检查到这个错误,对event声明的委托只能用+= 和-=来赋值。

41, 实现标准的事件模型。

微软规定用于事件的委托应以EventHandler结束,返回void类型,参数第一个为object类型的sender,表示事件的触发者,第二个参数为EventArgs类或它的派生类,命名要以EventArgs结束。多数情况下,我们使用系统自定义的EventHanlder<EventArgs>这个代理来定义事件就可以了,要传递自己的业务数据,可以派生一个如UploadEventArgs来实现。

42, 使用泛型参数兼容泛型接口的不可变性。

void PrintSalary<T>(ISalary<T> e)比void PrintSalary(ISalary<Emplyee> e)更具通用性。因为ISalary<Emplyee>是不可变的。

43, 让接口中的泛型参数支持协变。

在泛型参数上使用out关键字,表明泛型参数只能作为函数的返回值。有了out关键字,ISalary<Emplyee> ee = new BaseSalary<Manager>();的转型就是合法的。

44, 理解委托中的协变。

委托中的泛型变量,天生就具有部分协变性,比如你可以将一个返回子类的方法直接赋值给一个相应签名的父类的委托(前提是,泛型变量是返回值)。Public delegate T GetEmployeeHander<T>(string name); 我们可以直接用GetEmployeeHander<Employee> getEmployee = getManager;其中getManager是一个返回Manager类型的方法。但是下面这中情况就不行了,GetEmployeeHander<Manager> getManagerHander = getManager; GetEmployeeHander<Employee> getEmployee = getManagerHander;所以,如果确定泛型委托有可变性,应该加上一个out关键字。

45, 为泛型类型的参数指定逆变。

逆变的关键字是in,表明泛型参数只能用作函数的参数使用。既然是参数使用,那么子类当然可以代入它的父类。

时间: 2024-08-02 22:21:17

【进阶修炼】——改善C#程序质量(3)的相关文章

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

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

【进阶修炼】&mdash;&mdash;改善C#程序质量(9)

140,使用默认的访问修饰符. 如果不加访问修饰符,成员变量的默认是private的,类默认是internal的.为了明确访问的权限,我倒是建议都加上访问修饰符,这省不了多少代码. 141,不知道该不该加大括号的时候就加上. 大括号会多占用两行代码,到底一行语句的代码需不需要加大括号这是一个争论.但是为了避免引入不必要的bug还是加上吧. 142,总是提供有意义的命名. 我们不希望看到如iTemp的命名,类似于i的命名只应该出现在循环中.变量的命名应尽可能表达它应该表达的意思,不要太随意的命名,

【进阶修炼】&mdash;&mdash;改善C#程序质量(2)

16, 元素可变的情况下应避免用数组. 数组是定长的集合,可以考虑用ArrayList或List<T>集合.ArrayList元素是object类型,有装箱的开销,性能较低.另外Array类提供了Array.CreateInstance来创建数组,Array.Copy来拷贝数组,但这牵涉到新数组的创建,会增加开销. 17, 多数情况下用foreach代替for循环. 18, Foreach不能代替for. Foreach不能对元素进行增删操作,不能访问序号. 19, 使用对象初始化器和集合初始

【进阶修炼】&mdash;&mdash;改善C#程序质量(7)

113,声明变量时考虑最大值. Ushort的最大值是65535,用于不同的用途这个变量可能发生溢出,所以设计时应充分了解每个变量的最大值. 114,MD5不再安全. MD5多用于信息完整性的校验.R=H(S),MD5的算法是不可逆的,也就是我们几乎没有可能根据生产的MD5码去还原原文.但是我们可以使用穷举的办法生成MD5码来对比,由于我们平常设定的密码都比较简单,如:123456,根本不用很长的时间就会被破解掉.为了有效防止破解,一个可行的做法是为我们的密码固定加一个字符串"%¥#--@!&a

【进阶修炼】&mdash;&mdash;改善C#程序质量(6)

90,不应为抽象类指定public的构造函数. 抽象类即使指定了public的构造函数,也是不能实例化的,编译通不过.抽象类的构造函数应该设定为protected,它的作用应该是初始化自己的成员,以及可以被子类构造函数调用.设定为public权限毫无意义. 91,可见字段应该重构为属性. 属性比字段有更好的灵活性,可以加入代码控制,可以在类型内部实现线程安全访问,可以让类型得到通知(如WPF系统),这些都是字段所不具备的.当然,如果仅限于类型内部使用,应该用字段. 92,谨慎将数组或集合作为属性

【进阶修炼】&mdash;&mdash;改善C#程序质量(5)

71, 区分异步和多线程的应用场景. 计算机的很多硬件,如硬盘,光驱,声卡,网卡都有DMA(Direct Memory Access)功能,它可以不占用cpu的资源,而异步的提出恰恰就是基于这个的.而多线程是操作系统上的并行执行的代码,是会占用cpu资源的.所以关于这两种的使用场景建议是:1)对于I/0密集型操作使用异步.2)对于计算密集型操作使用多线程. 72, 在线程同步中使用信号量. 值类型是不能被锁定的,引用类型上的等待机制,分为锁定和信号同步.锁定通过lock关键字或Monitor来完

【进阶修炼】&mdash;&mdash;改善C#程序质量(4)

46, 显示释放资源,需要实现IDisposable接口. 最好按照微软建议的Dispose模式实现.实现了IDisposable接口后,在Using代码块中,垃圾会得到自动清理. 47, 即使提供了显示的释放方法,也应该在终结器中提供隐式实现. 因为我们不能保证用户会主动去调用这个释放方法,但我们要保证在垃圾回收时,这些资源能得到清理. 48, Dispose方法应该允许被多次调用. 我们可以创建一个变量disposed来标明对象是否被释放了. 49, 在Dispose模式中应提供一个受保护的

【进阶修炼】&mdash;&mdash;改善C#程序性能(1)

这是一个大纲形式的提点,以便自己可以花较少的时间时常浏览.在开发中,多加注意这些有用的建议,让自己成为一个更优秀的程序员.内容主要来自<编写高质量代码-改善C#程序的157个建议>(陆敏技),这本书写的真的很好,都是些实战经验的总结,建议大家购买此书,这其中的建议不光适合于C#,只要你做.NET开发,阅读此书都会从中受益.同时,如其他书籍和资料有好的建议,我也会不断更新到这里. 1, 字符串使用. 应避免发生装箱:避免分配额外的内存:考虑使用StringBuilder来替代string.str

Android 控件进阶修炼-仿360手机卫士波浪球进度控件

技术:Android+java 概述 像360卫士的波浪球进度的效果,一般最常用的方法就是 画线的方式,先绘sin线或贝塞尔曲线,然后从左到右绘制竖线,然后再裁剪圆区域. 今天我这用图片bitmap的方式,大概的方法原理是: (1)首先用clipPath裁剪园区域, (2)然后用4张图来不断绘制到画布上,再用偏移量来控制移动的速度,从而形成波浪动态效果. (3)有一点需要注意的是,裁剪圆的时候用到的clipPath这个方法,在android 4.1,和4.2等某些系统上,裁剪出来不是圆,而是矩形