zoukankan      html  css  js  c++  java
  • [.NET] 《Effective C#》快速笔记(四)- 使用框架

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

      .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# 高效编程要点补充


    【博主】反骨仔

    【原文】http://www.cnblogs.com/liqingwen/p/6797709.html 

    【GitHub】https://github.com/liqingwen2015/XMind 可以下载 XMind

    【参考】《Effective C#》

  • 相关阅读:
    ASP.NET MVC 视图
    ASP.NET MVC 控制器
    ASP.NET MVC 入门
    SQL 兼容性设置
    this template attempted to load component assembly 'NuGet.VsiualStudio.interop,version=1.0.0.0 culture=neutral publickeytoken=0000000'. 解决方案
    SQL 时间函数
    [原创]PageOffice+MobOffice 电脑、移动跨平台Office文档在线流转解决方案
    [原创]Java调用PageOffice给Word中的Table赋值
    [原创]Java调用PageOffice在线打开数据库中保存的Word文件
    [原创]新版PageOffice V4.0为什么用弹出窗口的方式打开文件?
  • 原文地址:https://www.cnblogs.com/liqingwen/p/6797709.html
Copyright © 2011-2022 走看看