摘要:
建议47:即使提供了显式释放方法,也应该在终结器中提供隐式清理 在标准的Dispose模式中,我们注意到一个以~开头的方法,如下: 这个方法叫做类型的终结器。提供类型终结器的意义在于,我们不能奢望类型的调用者肯定会主动调用Dispose方法,基于终结器会被垃圾回收这个特点,它被用作资源释放的补救措施 阅读全文
摘要:
建议46:显式释放资源需继承接口IDisposable C#中的每一个类型都代表一种资源,资源分为两类: 托管资源:由CLR管理分配和释放的资源,即从CLR里new出来的对象。 非托管资源:不受CLR管理的对象,如Windows内核对象,或者文件、数据库连接、套接字、COOM对象等。 如果我们的类型 阅读全文
摘要:
建议45:为泛型类型参数指定逆变 逆变是指方法的参数可以是委托或者泛型接口的参数类型的基类。FCL4.0中支持逆变的常用委托有: Func<int T,out TResult> Predicate<in T> 常用委托有: IComparer<in T> 下面例子演示了泛型类型参数指定逆变所带来的好 阅读全文
摘要:
建议44:理解委托中的协变 委托中的泛型变量天然是部分支持协变的。为什么是“部分支持协变”?看下面示例: 上中的GetAManager返回的是一个Manager,但是在使用中,其实是将其赋值给一个泛型参数为Employee的委托变量。因为存在下面一种情况,所以编译不过: 要让上面的代码编译通过,同样 阅读全文
摘要:
建议43:让接口中的泛型参数支持协变 除了上一建议中提到的使用泛型参数兼容接口不可变性外,还有一种办法是为接口中的泛型声明加上out关键字来支持协变,如下所示: 这段代码在FCL4.0以前是不能编译通过的,因为IEnumerable<T>这个接口在FCL中没有被声明为IEnumerable<out 阅读全文
摘要:
建议42:使用泛型参数兼容泛型接口的不可变性 让返回值类型返回比声明的类型派生程度更大的类型,就是“协变”。如: Programmer是Employee的子类,所以Programmer对象也是Employee对象。方法GetAEmployee返回一个Programmer的对象,也就是相当于返回一个E 阅读全文
摘要:
建议41:实现标准的事件模型 上一建议中,我们实现了一个带事件通知的文件传输类FileUploader。虽然已经满足需求,但却不符合C#的编码规范,查看EventHandler的原型声明: 我们应该知道微软为事件模型定义的几个规范: 委托类型的名称已EventHandler结束; 委托原型返回值为v 阅读全文
摘要:
建议40:使用event关键字为委托施加保护 在建议中我们实现了一个具有通知功能的文件传输类,如下: 像这样调用: 以上调用者代码本身是和FileUploader类一起的,这起码存在两个问题: 1)如果在Main中另起一个线程,该工作线程则可以将FileProgress委托链置为空: 2)可以在外部 阅读全文
摘要:
建议39:了解委托的实质 理解C#中的委托需要把握两个要点: 1)委托是方法指针。 2)委托是一个类,当对其进行实例化的时候,要将引用方法作为它的构造方法的参数。 设想这样一个场景:在点对点文件传输过程当中,我们要设计一个文件传输类,该传输类起码要满足下面几项功能: 传输问题件; 按照百分制通知传输 阅读全文
摘要:
建议38:小心闭包中的陷阱 先看一下下面的代码,设想一下输出的是什么? 我们的设计意图是让匿名方法(在这里表现为Lambda表达式)接受参数 i ,并输出: 0 1 2 3 4 而实际上输出为: 5 5 5 5 5 这段代码并不像我们想象的那么简单,要完全理解运行时代码是怎么运行的,首先必须理解C# 阅读全文