C#高效编程TIPS

来源:互联网 发布:淘宝达人定向申请 编辑:程序博客网 时间:2024/04/27 08:16

摘录自这个微博http://www.cnblogs.com/luminji/



1 as,is转型比强制转型的优势

优势在于as,is 不抛出异常,如果转型失败,则返回null

强制转型则会抛出异常,导致代码必须处理异常,效率低。

值得注意的是,as只能转型基本类型,对于基本类别如int等的转型,只能使用强制转型或is。


2:初始化器和构造器的异同
初始化器实际是语法,经编译后,它在构造函数的最开始执行。也就是说,初始化器可以理解为构造函数的一部分。

3 foreach不能替代for的原因
1: 首先,对集合的每次增删操作(是不是全部集合?不得而知,但是起码是绝大部分集合),都会让集合的version字段+1,foreach采用的是迭代器模式,每次迭代的时候都要判断version是不是保持一致,如果不一致,则抛出异常。而for没有这方面的限制。
 
List<int> list = new List<int>() { 0, 1, 2, 3 };
foreach (int item in list)
{
 list.Remove(item); 
 Console.WriteLine(item.ToString());
}
 
所以,采用会抛出异常,而改为for则不会。这是for不能被foreach取代叼的最重要原因。

event关键字的作用

既然使用委托也能实现回调,为什么又需要event关键字。答曰:event 最大的作用就是防止在类的外部触发类的事件。 

泛型参数的约束是不是应该叫约定更好

在泛型的使用过程中,常常使用到的一个功能就是为泛型参数设定约束。约束听上去像是限制了泛型参数的使用范围,而实际上,约束本身确实拓展了泛型参数的使用。

一个没有约束的泛型参数,只能具有object的行为和属性,而一个指定约束为Student的泛型参数,却可以使用类型Student的所有公开属性和方法。

所以,俺觉得约束这个词翻译的实在不好,叫约定多好。 


6:使用属性还是字段

 首先重大区别就是属性实质是方法,所以:
1:可以为属性添加代码;
2:可以让属性支持线程安全;见effective c#第一版的第一章;
3:属性得到了VS编辑器的支持,得以实现自动属性这种功能。
4:自动属性的特点在LINQ中得到了广泛应用,尤其是匿名类型中,只能实现只读的自动属性,匿名类型不支持字段;
5:从设计的角度,也就是面向对象的角度,建议使用属性;
6:如果某个属性仅仅作为类型内部使用,而且不涉及到上面5点内容,则建议使用字段

还有一点,属性在序列化中有点尴尬,由于属性是方法,所以不能为其指定[NonSerialized]特性。


7:线程同步有多少种方法?

 所谓线程同步,采用的技术,就是在某个对象上等待(也理解为锁定该对象)。C#中类型对象的分类:引用类型和值类型。在这两种类型上的等待是不一样的,我们也可以简单的理解为在CLR中,值类型是不能被锁定的(参考MSDN的volatile关键字)。

在引用类型上的等待,又分为两种技术:锁定和信号机制。

锁定使用:关键字lock和类型Monitor,前者其实是后者的语法糖。这是最常用的同步技术,小伙们应该都用过;

信号机制:信号机制中涉及的类型都继承自抽象类WaitHandle,这些类型有EventWaitHandle(类型化为AutoResetEvent、ManualResetEvent)和Semaphore以及Mutex。它们之间有一定的区别,值得一提的是Mutex能同步不同应用程序域。其它几个类型的不同点MSDN写的很伤人,而且未进行横向比较,简单来说,就是EventWaitHandle通过布尔型进行同步,其中AutoResetEvent又自动恢复类型的阻滞状态,ManualResetEvent则必须手动恢复阻滞状态。Semaphore通过整型进行同步。


8:不建议lock(this)

 1:如果两个对象的实例分别执行了lock(this)这样的代码,实际锁定的是两个对象,完全不能达到同步的目的。

2:最好避免锁定 public 类型或锁定不受应用程序控制的对象实例。例如,如果该实例可以被公开访问,则 lock(this) 可能会有问题,因为不受控制的代码也可能会锁定该对象。这可能导致死锁,即两个或更多个线程等待释放同一对象。出于同样的原因,锁定公共数据类型(相比于对象)也可能导致问题。


9:区分计算密集型和I/O密集型的多线程应用场景

I/O密集型操作。硬盘、网卡、声卡、显卡等都是。CLR所提供的异步编程模型就是让我们充分利用硬件的DMA功能来提高CPU的利用率。

一个在大多数情况下正确的技巧是,凡是FCL中类型提供了类似BeginDoSomething方法的,都建议使用这个异步调用来完成多线程编码,异步在后台调用线程池线程完成调度,最大化的节约了系统的性能。 



***************************************************************************************无聊的分割线***********************************************************************************