.NET 是一个类库,你了解的越多,自己需要编写的代码就越少。

目录

  • 三十、使用重写而不是事件处理函数
  • 三十一、使用 IComparable<T> 和 IComparer<T> 实现顺序关系
  • 三十二、避免使用 ICloneable 接口
  • 三十三、仅用 new 修饰符处理基类更新
  • 三十四、避免重载基类中定义的方法
  • 三十五、PLINQ 如何实现并行算法
  • 三十六、理解 PLINQ 在 I/O 密集场景
  • 三十七、注意并行算法中的异常

三十、使用重写而不是事件处理函数

  1.处理系统之中触发的事件:要么使用事件处理函数,要么重写基类中的虚方法。在派生类中,你只应该重写虚方法,而事件处理函数则应该使用在对象没有关系的交互中。

  2.从效率角度,重写也比事件处理函数更快,事件处理器需要迭代整个请求列表,这样占用了更多的CPU时间。

  3.但是,事件是在运行时绑定的,因此会带来更好的灵活性。

  4.一个事件处理器抛出异常,则事件链上的其他处理器将不会被调用,而重写的虚方法则不会出现这种情况。

  5.重写只能用于派生类中,其他类型必须使用事件机制。

三十一、使用 IComparable<T> 和 IComparer<T> 实现顺序关系

  1..NET 提供了两个接口 IComparable<T> 和 IComparer<T> 表示顺序关系。IComparable 定义了类型的自然顺序,而 IComparer 则表示描述其他顺序。

  2.IComparable 接口包含一个方法:CompareTo() 。如果当前对象 < 被比较对象,返回值 < 0;当前对象 > 被比较对象,返回值 > 0;两者相等,返回 0。

  3.实现非泛型的 IComparable 接口的原因:保证向后兼容,反射中使用泛型会加大难度。

  4.实现 IComparable 时请使用显示接口实现,并提供一个强类型版本的重载,这个强类型的重载能提高性能,并降低使用者误用 CompareTo 方法的可能。

三十二、避免使用 ICloneable 接口

  1.当对象关系复杂时,深复制会带来不必要的麻烦。

  2.对于内建类型,如整数,深复制和浅复制的结果一样。

  3.內建的值类型不需要支持 ICloneable。赋值语句就可以复制结构中所有的值,且比 Clone() 更高效;而子类,仅在真正需要复制操作时再添加 ICloneable 支持。

  4.对于值类型,永远不要实现 ICloneable,直接使用赋值操作即可。

三十三、仅用 new 修饰符处理基类更新

  1.new 修饰符必须小心谨慎的使用。如果它是有歧意的,就等于在类上创建了个模糊的方法。

  2.只有在特殊情况下才使用,那就是升级基类时与你的类产生冲突时。即使在这种情况下,也应该小心的使用它。最重要的是,其它任何时候都不要用它。

三十四、避免重载基类中定义的方法

  1.为基类中定义的方法创建重载增加了重载解析时的可选项,也就是增加了二义性。很可能你对重载选择的理解和编译期的解析并不相同,从而造成了用户的困惑。解决办法:选择不同的名称,因为这个类是你设计的,自然就可以给出更好,不同的的方法名称。

  2.不要重载那些定义于基类中的方法,这不能带来丝毫意义,只能给使用者平添烦恼,但不针对重写。

三十五、PLINQ 如何实现并行算法

  1.使用时简单的添加 AsParallel() 即可。

  2.PLNQ 在能够保证正确性的前提下,让程序得到多核环境下的性能提升。

  3.需要理解何时数据访问是必须同步的,也需要衡量 ParallelEnumerable 中并行和顺序版本方法带来的影响。

  4.PLINQ 无法并行化 LINQ to SQL 或 EF 的执行,因为这两样东西会借助数据库引擎来执行并行查询。

  5.每个并行查询都开始于一个分区的操作,PLINQ 需要对输入元素分区,然后指派给负责执行查询的任务。

  6.4 种分区算法:单位分区、区块分区、条带分区和散列分区。

  7.3 种其它算法:管道(Pipelining)、停止并进行(Stop&Go)和反向枚举。

  8.通过在查询开始时添加 AsParallel() 方法,将查询表达式转换成并行执行。

            var list = new List<int>();
var query=list.Where(x=>x<150).Select(x=>x.ToString()); //并行查询
var queryParallel = list.AsParallel().Where(x => x < 150).Select(x => x.ToString());

三十六、理解 PLINQ 在 I/O 密集场景

            var urls = new List<string>();
foreach (var url in urls)
{
var result = new WebClient().DownloadData(url); //发出一个同步的 Web 请求,然后等待接收数据,主要会将时间浪费在等待上
Console.WriteLine(result);
} //使用并行处理模型
Parallel.ForEach(urls, url =>
{
var result = new WebClient().DownloadData(url);
Console.WriteLine(result);
}); //使用 PLINQ
var results = from url in urls.AsParallel()
select new WebClient().DownloadData(url);
results.ForAll(Console.Write);

  1.PLINQ 的执行方式和并行任务库的 Parallel.ForEach() 不同。PLINQ 使用固定数目的线程,而 Parallel.ForEach() 会调整线程的数量来增加吞吐量。

  2.那些混合了 I/O 密集和 CPU 密集的操作来说,Parallel.ForEach() 更适合。Parallel.ForEach() 会根据当前的负载动态调整线程数量。当很多线程因为等待 I/O 操作而阻塞时,Parallel.ForEach() 会创建更多的线程提高吞吐量。当很多线程都在工作时,Parallel.ForEach() 也会限制活动线程的数量,降低上下文切换的代价。

  3.对于那些需要访问其他计算机,并等待远程响应的程序来说,并行任务库和 PLINQ 起到很重要的作用。

三十七、注意并行算法中的异常

  1.后台线程中发生的异常会在不同的方面增加复杂度。异常不能穿过线程边界保留调用栈,当异常传递到开始线程的方法时,线程就会中止。调用线程无法捕获这个错误,也就不能进行对应的处理。

  2.一旦后台线程抛出异常,其它的后台操作也会停止。最好是不要在并行算法中抛出异常。不过其它意料之外的异常也可能会出现。

本系列

  《Effective C#》快速笔记(一)- C# 语言习惯

  《Effective C#》快速笔记(二)- .NET 资源托管

  《Effective C#》快速笔记(三)- 使用 C# 表达设计

  《Effective C#》快速笔记(四) - 使用框架

  《Effective C#》快速笔记(五) - C# 中的动态编程

  《Effective C#》快速笔记(六) - C# 高效编程要点补充

《Effective C#》快速笔记(四)- 使用框架的更多相关文章

  1. [.NET] 《Effective C#》快速笔记(四)- 使用框架

    <Effective C#>快速笔记(四)- 使用框架 .NET 是一个类库,你了解的越多,自己需要编写的代码就越少. 目录 三十.使用重写而不是事件处理函数 三十一.使用 ICompar ...

  2. [.NET] 《Effective C#》快速笔记(三)- 使用 C# 表达设计

    <Effective C#>快速笔记(三)- 使用 C# 表达设计 目录 二十一.限制类型的可见性 二十二.通过定义并实现接口替代继承 二十三.理解接口方法和虚方法的区别 二十四.用委托实 ...

  3. [.NET] 《Effective C#》快速笔记 - C# 中的动态编程

    <Effective C#>快速笔记 - C# 中的动态编程 静态类型和动态类型各有所长,静态类型能够让编译器帮你找出更多的错误,因为编译器能够在编译时进行大部分的检查工作.C# 是一种静 ...

  4. [.NET] 《Effective C#》快速笔记 - C# 高效编程要点补充

    <Effective C#>快速笔记 - C# 高效编程要点补充 目录 四十五.尽量减少装箱拆箱 四十六.为应用程序创建专门的异常类 四十七.使用强异常安全保证 四十八.尽量使用安全的代码 ...

  5. [.NET] 《Effective C#》快速笔记(二)- .NET 资源托管

    <Effective C#>快速笔记(二)- .NET 资源托管 简介 续 <Effective C#>读书笔记(一)- C# 语言习惯. .NET 中,GC 会帮助我们管理内 ...

  6. [.NET] 《Effective C#》快速笔记(一)- C# 语言习惯

    <Effective C#>快速笔记(一)- C# 语言习惯 目录 一.使用属性而不是可访问的数据成员 二.使用运行时常量(readonly)而不是编译时常量(const) 三.推荐使用 ...

  7. 《Effective C#》快速笔记(一)- C# 语言习惯

    目录 一.使用属性而不是可访问的数据成员 二.使用运行时常量(readonly)而不是编译时常量(const) 三.推荐使用 is 或 as 操作符而不是强制类型转换 四.使用 Conditional ...

  8. 《Effective C#》快速笔记(六)- - C# 高效编程要点补充

    目录 四十五.尽量减少装箱拆箱 四十六.为应用程序创建专门的异常类 四十七.使用强异常安全保证 四十八.尽量使用安全的代码 四十九.实现与 CLS 兼容的程序集 五十.实现小尺寸.高内聚的程序集 这是 ...

  9. 《Effective C#》快速笔记(五)- - C# 中的动态编程

    静态类型和动态类型各有所长,静态类型能够让编译器帮你找出更多的错误,因为编译器能够在编译时进行大部分的检查工作.C# 是一种静态类型的语言,不过它加入了动态类型的语言特性,可以更高效地解决问题. 一. ...

随机推荐

  1. python新手之字典增删改查

    一.字典的定义 city_list = { 'beijin':"北京",'shanghai':"上海" } print(city_list) 二.字典添加一个元 ...

  2. 使用bison和yacc制作脚本语言(2)

    我们先来想一下语法 一般脚本语言不需要定义类型直接在赋值的时候确定 我们主要考虑一下变量的类型 a = 1; b = 1.1; c = "str"; 一般来讲,我们使用这三种类型, ...

  3. 反射vs简单工厂模式

    interface Computer { void printpc(); } class lenovo implements Computer { @Override public void prin ...

  4. 北京Uber优步司机奖励政策(12月16日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  5. DBoW2 词袋模型笔记

    DBoW算法用于解决Place Recognition问题,ORB-SLAM,VINS-Mono等SLAM系统中的闭环检测模块均采用了该算法.来源于西班牙的Juan D. Tardos课题组. 主要是 ...

  6. springBoot -webSocket 基于STOMP协议交互

    浅谈WebSocket WebSocket是在HTML5基础上单个TCP连接上进行全双工通讯的协议,只要浏览器和服务器进行一次握手,就可以建立一条快速通道,两者就可以实现数据互传了.说白了,就是打破了 ...

  7. R语言使用过程中出现的问题--读取EXCEL文件

    方法一: 按照R导论中的方法,使用RODBC包, library(RODBC) channel<-odbcConnectExcel("file.xlsx") da2<- ...

  8. Ubuntu—安装网络调试工具

    https://pan.baidu.com/s/1G6oHXp3SvcN6HMAMqTdqhA 1,在ubuntu的终端下,切换到网络调试工具所在的目录 $ cd 桌面/    #我的放在桌面上 2, ...

  9. clientHeight、offsetHeight、scrollHeight、clientTop、scrollTop、offsetTop的对比

    首先,这些都是dom节点的属性. 高宽属性:clientHeight:html元素不含border的高度. 对于box-sizing不同的情况,有些地方需要注意一下.当box-sizing为conte ...

  10. facebook演讲

    任何为了更大愿景工作的人,可能会被称为疯子,即使你最终获得成功. 任何为了复杂问题工作的人,都会因为不能全面了解挑战而被指责,即使你不可能事先了解一切. 任何抓住主动权先行一步的人,都会因为步子太快而 ...