该书并不是简单的语言新特性介绍,而是介绍如何使用这些特性帮你解决每天都要遇到的实际问题。

Item1 使用属性而不是可访问的数据成员

属性这个语言元素可以让你像访问数据成员一样使用,但其底层却使用方法实现。因为属性是使用方法来实现的,所以添加多线程支持也非常简单。很容易即可在属性的get和set访问器中作出如下的修改,从而支持对数据的同步访问:

public class Customer
{private object syncHandle = new object();private string m_name;public string Name{get{lock(syncHandle)return m_name;}set{if(string.IsNullOrEmpty(value)){throw new ArgumentException("Name cannot be blank","Name");lock(syncHandle)name=value;}}}
}

Item2 用运行时常量(readonly)而不是编译期常量(const)

C#有两种类型的常量:编译期常量和运行时常量。虽然编译期常量略微快一些,但是却没有运行时常量那么灵活。编译期常量(const)仅能用于数字和字符串。运行时常量 (readonly)也是一种常量可以为 任意类型,运行时常量必须在构造函数或者初始化器中初始化。

二者最重要的区别在于,readonly值是在运行时解析的。 引用 一个readonly常量时生成的IL引用 的是readonly变量,而不是其值。编译期常量将生成同样的IL,就像直接在代码中给出数字一样,即使跨程序集也是如此,即使另一个程序集中引用 了某个程序集中的某个常量 ,相应常量也会被直接替换成这个值。这将对程序运行时的兼容性产生深远影响。

Item3 正确地初始化静态成员变量

静态构造函数是一个特殊的函数,将在其他所有方法执行之前以及 变量或属性被第一次访问之前执行。你可以使用这个函数来初始化静态变量、实现单例模式或执行类可用之前必须进行的任何操作。你不应该使用实例构造函数、专门的私有函数或其他什么方式来初始化静态变量。

和实例初始化一样,也可以使用初始始化器语法来替代静态的构造函数。若只是某个静态成员 分配空间,那么不妨使用初始化器语法。而若是以更复杂 一些的逻辑来初始化成员变量,那么可以使用静态构造函数。

在C#中实现单例模式是静态构造函数最常用的一个场景。只需要将实例构造函数声明为私有,然后添加一个初始化器即可:

public class Mysingleton
{private static readonly Mysingleton m_instance = new Mysingleton();public static Mysingleton Instance{get {return m_instance;}}private Mysingleton(){}
}

单例模式也可以如此简单地实现,除非你还有更加复杂的用来初始化单例的逻辑:

public class Mysingleton2
{private static readonly Mysingleton2 m_instance;static Mysingleton2(){m_instance = new Mysingleton2();}public static Mysingleton2 GetInstance{get {return m_instance}}private Mysingleton2(){}
}

与实例的初始化器类似,静态初始化器在任何静态构造函数调用之前执行。而且,静态初始化器在调用基类的静态构造函数之前执行。

在应用程序作用域内,在你的类型被第一次访问之前,CLR会自动调用你的静态构造函数。若某个异常被静态构造函数抛出,那么CLR将终止你的程序。CLR无法通过静态构造函数初始化该类型,而且也不会再次尝试,导致该类型并没有被正确初始化。

使用静态构造函数而不是静态初始化器的最觉见理由是处理异常。在使用静态初始化器时,我们无法自己捕捉异常,而在静态构造函数中却可以做到。

Item4 避免创建非必要的对象

GC能够帮你很好地管理内存,也会以一种非常高效的方式来移除内存中的垃圾对象。不过不管有多高效,分配和销毁在堆上的对象总会花费掉时间。若是在某个方法中创建了太多的引用对象,那么将会对程序的性能产生严重的影响。

因此,不要给GC带来太多的负担。这里有一些规则,可以让你尽量降低GC的工作量。所有的引用类型,包括那些局部变量,都会分配在堆上。在函数之后,函数内的所有局部变量都会立即变成垃圾。一个很觉的错误做法就是在窗体的Paint处理函数中创建GDI对象:

protected override void OnPaint(PainEventArgs e)
{
using (Font pFont = new Font("Arial",10.0f))
{
e.Graphics.DrawString(DateTime.Now.ToString(),
pFont,Brushes.Black,new PointF(0,0));
}
base.OnPaint(e);
}
不过若是将Font之类实现了IDisposable接口的局部变量提升成成员变量,那么类本身也要实现IDisposable接口。前面使用的静态属性Brushes.Black演示了另一个避免重复创建类似对象的方法。创建静态成员变量可以让引用类型在类的各个实例中共享。Brushes类中包含了一系列的静态Brush对象,每个都包含了一种常用 的颜色。Brushes类的内部使用延迟求值的方式根据具体的需要创建笔刷,其简要的实现如下:

private static Brush blackBrush
public static Brush Black
{
get
{
if(blackBrush==null)
blackBrush=new SolidBrush(Color.Black);
return blackBrush;
}
}

Item5 实现标准的销毁模式

类型继承体系中的基类应该实现IDisposable接口来释放资源。该类型也应该添加一个终结器作为最后的保护手段。这两具处理均应该把具体的释放资源工作转交给一个虚方法执行,且该 虚方法可由其派生类根据自己的需要覆写。仅在派生类必须释放自己的非托管资源时,才应该覆写该虚方法,且覆写时也必须调用基类的版本。

在GC运行时,它会立即清理掉那些没有提供终结器的垃圾对象。而提供了终结器的垃圾对象会停留在内在中,被添加到一个叫做“终结队列”(finalization queue)的地方。GC会使用另一个线程来执行队列中的对象的终结器。终结器完成工作之后,这些垃圾对象才能从内存中清理出去。那些需要终结的对象停留在内存中的时间要远远长于普通对象,不过也只能这样。

实现IDisposable接口是一种标准的做法,用来通知使用者和运行时系统该对象包含的资源需要及时释放。IDisposable接口仅定义了一个方法:

public interface IDispoable
{void Dispose();
}

IDisposable.Disposable方法的实现中需要完成如下4个任务:

1、释放所有非托管资源。

2、释放所有托管资源,包括释放事件监听程序。

3、设定一个状态标志,表示该对象已经被销毁。若是在销毁后再次调用对象的公有方法,那么应该抛出ObjectDisposed异常。

4、跳过终结操作,调用GC.SuppressFinalize(this)即可。

C#高效编程--改进C#代码的50个行之有效的办法笔记相关推荐

  1. 【笔记】《C#高效编程改进C#代码的50个行之有效的办法》第1章C#语言习惯(1)--属性的特性以及索引器(SamWang)...

    ************************************************************************** 书名:<C#高效编程改进C#代码的50个行之 ...

  2. C#高效编程 改进C#代码的50个行之有效的办法(第2版)

    Effective  C# 50 Specific Ways to Improve Your C# Sencond Edition 第一章 C#编程习惯 条目1 使用属性而不是访问的数据成员 条目2 ...

  3. C#高效编程:改进C#代码的50个行之有效的办法(第2版)(奋斗的小鸟)_PDF 电子书

    下载地址:http://pan.baidu.com/share/link?shareid=1689099661&uk=721744522 QQ:2864670220  (提供电子书提取密码) ...

  4. 计数排序及其改进 C++代码实现与分析 恋上数据结构笔记

    文章目录 复习梗概 算法思想 基础思想 改进空间复杂度,改进不能对负数进行排序问题 改进稳定性 计数排序时间空间复杂度 计数排序基础版 代码及输出 计数排序第一次改进版 代码及输出 计数排序终极版 代 ...

  5. c语言函数除法代码,C语言高效编程与代码优化~

    原标题:C语言高效编程与代码优化~ 译文链接:http://www.codeceo.com/article/c-high-performance-coding.html 英文原文:https://ww ...

  6. 【Python】python初学者应该知道与其他语言差异化的高效编程技巧(附测试代码+详细注释)

    目录 1. 交换变量 2. 集合去重 3. 列表推导.集合推导和字典推导 4. 统计字符串中各个字符出现的次数 5.优雅地打印JSON数据 6.行内的if语句 6. 符合正常逻辑的数值比较 7. 田忌 ...

  7. 6. 设计模式之迭代思维:如何高效编程?

    一.什么是高效编程? 在编程的路上,你是不是曾有过这样的经历:虽然学会一门编程语言后会写代码了,但是有时写出的代码可能并没有想象的那么好.比如: 你的代码只要没有经过测试,发布上线后总是会频繁发生故障 ...

  8. 提高Python编程的效率技巧你知道哪些?收藏必备系列,阿里表哥推荐!Python高效编程技巧

    Python高效编程技巧 工作中经常要处理各种各样的数据,遇到项目赶进度的时候自己写函数容易浪费时间. Python 中有很多内置函数帮你提高工作效率! 一:在列表,字典中根据条件筛选数据 1.假设有 ...

  9. matlab编程实际应用,MATLAB高效编程技巧与应用:25个案例分析

    第一部分 高效编程技巧 第1章 MATLAB快速入门 1.1 熟悉MATLAB环境 1.1.1 MATLAB的启动 1.1.2 MATLAB desktop 1.1.3 MATLAB 程序编辑器(Ed ...

最新文章

  1. python参数类型限定_python限定方法参数类型、返回值类型、变量类型等|python3教程|python入门|python教程...
  2. 多线程利器-队列(queue)
  3. yjv是电缆还是电线_BVV属于电线还是电缆?
  4. python 延时_理解Python多线程5:加锁解决问题,但又带来麻烦!
  5. ntp linux 使用,linux-ntp 使用
  6. Ubuntu 18.04 Server必须使用netplan命令配置IP地址
  7. php使用iis6,php是与IIS6配合使用,搭建FastCGI环境
  8. 介绍一个产品的思维导图_思维导图介绍(1)
  9. 2月之最---2012年最后一个2月((*^__^*) )
  10. 谷歌浏览器和对应驱动器的安装、配置(附有安装包)
  11. CAN总线标准及协议分析
  12. 下列不是python的注释方式_以下不是python的注释方式是( )_学小易找答案
  13. 优动漫PAINT实用宝典(图层篇)——栅格图层
  14. 物理系统——射线检测
  15. 3.2Abstraction data type
  16. 六度分离理论在社会工程学中的应用
  17. 出行必备:手机1秒调出健康码 !
  18. 清华“差生”10年奋斗经历,只写事业,不写女人
  19. 超越 FPN 和 NAS-FPN!商汤港中文提出 FPG,特征金字塔网格强势登场!
  20. 整站优化提升排名工具_百度快速排名教程【常见问题】

热门文章

  1. 博士申请 | 香港理工大学智能计算实验室招收机器学习方向全奖博士/RA/博后
  2. 上海某外企网络工程师面试题「含答案」
  3. 网络规划 华为模拟器ensp
  4. 动力学分析基础(一)
  5. eclipse连接SQL Server数据库(详解很细心)
  6. incaseformat蠕虫病毒的预防措施及应对措施
  7. 乐鑫Esp32学习之旅14 esp32 sdk编程实现门户强制认证,连接esp32热点之后,自动强制弹出指定的登录html界面。(附带Demo)
  8. TCRT5000循迹模块原理及应用
  9. 立象(ARGOX) 条码标签打印机通用库 PLLB(BWIN-SCAPI)
  10. theano 这磨人的小妖精