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. 解决 p0sixspwn-v1.0.4 win版 无法定位程序输入点sqlite3_wal_checkpoint的问题

    p0sixspwn-v1.0.4 win版今天早晨发现大神( @winocm · @iH8sn0w · @SquiffyPwn) 已经发布. 下载下来运行之,发现会报错: 无法定位程序输入点sqlit ...

  2. windows下php的各个版本下载地址

    windows下php的各个版本 https://windows.php.net/downloads/releases/archives/

  3. Hadoop创建/删除文件夹出错

    log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFact ...

  4. 牛腩学用MUI做手机APP

    斗鱼直播间直播学习撸码,最终目标是用MUI做一个手机APP(暂定android平台,攒钱买IPHONE 7SE!!!),直播内容含整个软件APP的制作过程(含后台接口的制作,放到自己买的阿里云服务器, ...

  5. IIS配置,权限

      2. cd  C:\Windows\Microsoft.NET\Framework64\v4.0.30319 3. aspnet_regiis.exe -i Chen 19:04:42 %wind ...

  6. 浏览器自动转换URL编码产生乱码问题

    如果网址中含有汉字,浏览器会自动将其转换成URL编码,而在接收端,它又自动转换回来. 大部分时候都没什么问题,但有时候就很讨厌.因为生成这种URL编码,编码时的字符集和解码字符集不一定相同,比如编码时 ...

  7. 菜鸟学Java(十五)——Java反射机制(二)

    上一篇博文<菜鸟学编程(九)——Java反射机制(一)>里面,向大家介绍了什么是Java的反射机制,以及Java的反射机制有什么用.上一篇比较偏重理论,理论的东西给人讲出来总感觉虚无缥缈, ...

  8. Multi-cloud Kubernetes with Triton

    https://www.joyent.com/blog/triton-kubernetes-multicloud While running an experimental Kubernetes cl ...

  9. [Windows Azure] About Affinity Groups for Virtual Network

    Affinity groups are the way to group the services in your Windows Azure subscription that need to wo ...

  10. Android 编程下将 Bitmap 转为 InputStream

    某些情况下会用到这种非主流的转换方式,最近项目中用到,记录下. ByteArrayOutputStream baos = new ByteArrayOutputStream(); bm.compres ...