16, 元素可变的情况下应避免用数组。

数组是定长的集合,可以考虑用ArrayList或List<T>集合。ArrayList元素是object类型,有装箱的开销,性能较低。另外Array类提供了Array.CreateInstance来创建数组,Array.Copy来拷贝数组,但这牵涉到新数组的创建,会增加开销。

17, 多数情况下用foreach代替for循环。

18, Foreach不能代替for。

Foreach不能对元素进行增删操作,不能访问序号。

19, 使用对象初始化器和集合初始化器。

这是在.net 3.5以后增加的语法,在Linq查询结果的匿名类上只能使用对象初始化器赋值。

20, 使用泛型集合替代非泛型集合。

类似于ArrayList这种非泛型集合,没有类型安全性检查,并伴随有装箱、拆箱等性能损耗。

21, 选择合适的集合。

List<T>平时用的最多,它追加数据比较快,但是插入和删除数据比较慢,因为插入点以后的数据要全部移动。LinkedList,这是双向链表,插入和删除数据都较快,它没有Add方法,只有AddAfter,AddFirst等方法。Dictionary<K,V>这是一个基于散列值的字典类,查询速度较快,不允许有重复的键值。HashSet<T>,这是集在.net中的实现,存储无序的不重复的元素,如你重复两次添加2进去,最后一次没有效果,但不会出错。根据前面几个基本类型,可以衍生出可以排序的SortedList,SortedDictionary,SortedSet。另外在多线程环境中使用的ConcurrentBag(对应List),ConcurrentDictionary,ConcurrentQueue,ConcurrentStack。

22, 确保集合的线程安全。

多线程访问同一集合,应考虑使用lock关键字对使用集合的代码进行锁定。或可以考虑上面提到的在多线程环境下使用的集合。

23, 避免将List<T>作为自定义集合类的基类。

应该以组合的方式将List<T>包含在自定义类中,然后扩展相应的泛型接口IEnumerable<T>和ICollection<T>(或ICollection<T>的子接口如IList<T>),前者规范了迭代行为,后者规范了集合的操作。原因是List<T>几乎没有提供可供子类复写的方法。如果要向Add方法中加入自己的逻辑,只能覆盖(new关键字)这个方法,而使用者并不知道我们改变了这个意图,他认为自定义类还是一个List<T>,结果就是添加的结果和他预想的不一致。

24, 迭代器应该是只读的。

集合的迭代行为应该是固定的,不能被随意改变。

25, 谨慎集合属性的可写操作。

集合属性的创建,应该由对象内部完成,外界只能访问这个集合,而不应该允许设置成其他的集合。可以对属性使用private set来控制。

26, 使用匿名类型存储Linq查询的结果。

匿名类型可以临时存储数据,避免代码膨胀,过度设计大量的自定义类。匿名类型支持智能感知,匿名类型和Linq搭配使用大有用途。

27, 在查询中使用Lambda表达式。

Linq本质上是使用扩展方法和Lambda表达式来实现的。Linq的大部分扩展方法都是针对Action,Func,Predicate这几个泛型委托的,而Lambda其实就是一个简洁的委托,它可以简化代码。=> 左边是函数的参数,右边是函数体。

28, 理解延迟求值和主动求职的区别。

Linq表达式是一种延迟求值,只有使用时才会正真的计算值,如foreach时,或者调用ToList()方法时。理解这一点很重要,可以避免一些不必要的计算开销。

29, 区别Linq查询中的IEnumerable<T>和IQueryable<T>。

Linq查询方法提供了两类扩展方法,一类放在System.Linq.Enumerable类中,一类放在System.Linq.Queryable中。Enumerable中的扩展方法是对本地集合进行查询,查询的参数是Func<>,适合于Linq to Objects。Queryable中的扩展方法参数是Expression<Func<>>表达式树,这是针对Linq to SQL的,表达式树会被翻译成对应的SQL文。

30, 使用Linq取代集合中的比较器和迭代器。

Linq的orderby等语法实质是调用了IEnumerable的扩展方法来进行排序,这比让类型实现IComparable接口或自定义ICompare接口有更好的扩展性,并且代码更加简洁。

31, 避免不必要的迭代。

这一点说明的是Linq查询的条件应更加具体,如我们只需要第一条数据,可以加一个First()方法,只需要前5条数据,可以加一个Take(5)方法。当满足我们设置的这些条件时,结果就会返回,从而避免不必要的后续迭代。

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

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

    这是一个大纲形式的概要,以便自己可以花较少的时间反复阅读.在开发中,多加注意这些有用的建议,让自己成为一个更优秀的程序员.内容主要来自<编写高质量代码-改善C#程序的157个建议>(陆敏技 ...

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

    158,不要写冗余注释. 注释应该写代码没有表达的东西. 代码能够自我描述就不要加注释. 159,废弃的注释应该尽早删除. 废弃的注释由于年代太久远,已经和现在的代码逻辑不匹配了,这样的注释只会误导人 ...

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

    140,使用默认的访问修饰符. 如果不加访问修饰符,成员变量的默认是private的,类默认是internal的.为了明确访问的权限,我倒是建议都加上访问修饰符,这省不了多少代码. 141,不知道该不 ...

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

    122,以<Company>.<Component>作为命名空间. 如Microsoft.Windows.Design.也可以用域名作为空间,如www.microsoft.co ...

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

    113,声明变量时考虑最大值. Ushort的最大值是65535,用于不同的用途这个变量可能发生溢出,所以设计时应充分了解每个变量的最大值. 114,MD5不再安全. MD5多用于信息完整性的校验.R ...

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

    90,不应为抽象类指定public的构造函数. 抽象类即使指定了public的构造函数,也是不能实例化的,编译通不过.抽象类的构造函数应该设定为protected,它的作用应该是初始化自己的成员,以及 ...

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

    71, 区分异步和多线程的应用场景. 计算机的很多硬件,如硬盘,光驱,声卡,网卡都有DMA(Direct Memory Access)功能,它可以不占用cpu的资源,而异步的提出恰恰就是基于这个的.而 ...

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

    46, 显示释放资源,需要实现IDisposable接口. 最好按照微软建议的Dispose模式实现.实现了IDisposable接口后,在Using代码块中,垃圾会得到自动清理. 47, 即使提供了 ...

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

    32, 总是优先考虑泛型. 泛型代码有很好的重复利用性,和类型安全性. 33, 应尽量避免在泛型类中声明静态成员. 静态成员达不到共享的目的.List<int>和List<Strin ...

随机推荐

  1. android surfaceView 的简单使用 画图,拖动效果

    前面说到了画图,其实更好的就是使用 surfaceView了. surfaceView 继承于 View,View里面嵌套了一个专门用于画图的 surface, 对于一个View的onDraw()方法 ...

  2. Java Date and Calendar examples

    Java Date and Calendar examples This tutorial shows you how to work with java.util.Date and java.uti ...

  3. React Native 错误锦集

    启动时报错 : React Native version mismatch. JavaScript version: 0.57.4 Native version: 0.55.2 解决方案传送门:htt ...

  4. BT5配置网络

    root@bt:~# vi /etc/network/interfaces 编辑IP地址auto eth0#iface eth0 inet dhcpiface eth0 inet staticaddr ...

  5. 解决NavicatPremium导入CSV文件中文乱码的问题

    在做数据对接导入的时候对方提供的数据是CSV格式的文件 一开始用Excel打开时发现格式就不对,后来发现只要用Excel打开,就会破坏里面的格式 然后想先用NaviCat导入CSV再转成Excel格式 ...

  6. grub配置指南

    GRUB(统一引导装入器)是基本的Linux引导装入器.其有四个作用,如下:1.选择操作系统(如果计算机上安装了多个操作系统).2.表示相应引导文件所在的分区.3.找到内核.4.运行初始内存盘,设置内 ...

  7. [LintCode] Subarray Sum & Subarray Sum II

    Subarray Sum Given an integer array, find a subarray where the sum of numbers is zero. Your code sho ...

  8. ios block一定会犯的几个错误

    贴几段斯坦福大学关于gcd的代码,这段代码逐步演示了如何修正错误,其中用到的既是串行队列   1.这个是原始代码 - (void)viewWillAppear:(BOOL)animated { NSD ...

  9. Filberder教程

    http://www.cnblogs.com/TankXiao/archive/2012/02/06/2337728.html

  10. 灾备系统的评判指标:RTO、RPO

    RTO(RecoveryTime Object)是指灾难发生后,从IT系统崩溃导致业务停顿之刻开始,到IT系统恢复至可以支持各部门运作,业务恢复运营之时,此两点之间的时间段称为RTO. RPO(Rec ...