一.关于装箱与拆箱
看这两篇文章
http://www.cnblogs.com/mqsuper/archive/2008/08/12/1265520.html
http://www.cnblogs.com/wjiang/archive/2010/12/29/1920474.html
需要注意的点
- 尽量使用泛型集合
- 方法传参数时注意数据类型,减少装箱次数
- 结构体需要整体替换改变,内部属性改变无效
- 不要使用值类型和字符串相加(以前这被认为是一个技巧),会导致装箱
二.对象的相等性和同一性
int a = 1; int b = 1; Console.WriteLine(a.Equals(b)); Console.WriteLine(ReferenceEquals(a, b));
对象的Equals方法可以重写,所以无法得知相等性,ReferenceEquals则比较引用地址
有没发现ReferenceEquals使得值类型又装箱了
==与!=通常会调用内部的Equals方法
三.Dispose模式
参考此篇文章
http://www.cnblogs.com/wing011203/archive/2010/01/14/1648176.html
即为了防止用户忘记手动释放非托管资源,而在析构函数中释放资源.
当然也可以手动释放,dispose模式遵照着一定的规则,并没什么奥妙.之前我的理解是如何不通过在析构函数中自动调用Dispose方法,这个想法是错误的.还是通过析构函数中调用Dispose方法.仅仅需要记住其实现的步骤就可以了。
四.显式隐藏从基类继承的成员
public class A { public void Test() { Console.WriteLine("A"); } } public class B : A { new public void Test() { Console.WriteLine("B"); } } public class C : B { new public void Test() { Console.WriteLine("c"); } } public static void Main() { A a = new B(); a.Test(); A b = new C(); b.Test();
五.常量
除非确定不会更改,否则不要用常量.常量如静态字段,但不用static关键字,
public const int aa = 1;
需要注意的是,若其他程序集使用了这个常量,若重新修改这个常量重新编译,其他程序集也不会起作用,也需要重新编译.
六.事件引发
主要在于变量的判定问题。
版本一.
public event EventHandler Click; private void OnClick(EventArgs e) { if (Click != null) Click(this, e); }
在多线程情景下,Click作为一个公开事件可能在一个线程中事件尚未触发完成,但在另一个线程中则移除了这个事件,就会导致Click事件变为空.所以更正如下
private void OnClick(EventArgs e) { var temp = Click; if (temp != null) temp(this, e); }
使用内部的一个变量,则可以修正这个错误。
七.事件的实质
事件的本质就是委托回调.当定义了一个事件后,编译器会生成相关代码。
public void add_Click(EventHandler value) { EventHandler handler2; EventHandler click = this.Click; do { handler2 = click; EventHandler handler3 = (EventHandler)Delegate.Combine(handler2, value); click = Interlocked.CompareExchange<EventHandler>(ref this.Click, handler3, handler2); } while (click != handler2); } public void remove_Click(EventHandler value) { EventHandler handler2; EventHandler click = this.Click; do { handler2 = click; EventHandler handler3 = (EventHandler)Delegate.Remove(handler2, value); click = Interlocked.CompareExchange<EventHandler>(ref this.Click, handler3, handler2); } while (click != handler2); }
以上以线程安全的方式来添加和移除一个委托,所以添加事件和注销事件就是对委托的操作。
八.显示的事件实现
若不使用.net内置的事件语法,可以直接通过操作委托来实现一套事件管理机制.
可以参考上述事件的实现方式,将委托存在Dictionary中.具体参考CLR VIA C#(第3版)