今天,我们来回顾一下C#中的一些关键字,并深入理解一下他们。然后聊一下C#中容易引起混淆的一些东西,我们来看一下书中对它们的解释。2012-03-15
new:
我们从多方面讨论new。
- 作为运算符,用于创建对象和调用构造函数。这是我们最常用的,比方说Object a = new Object();。它在内存中到底做了什么,我们在这里就不深究了。
- 作为修饰符,用于向基类成员隐藏继承成员。这主要是针对版本控制而言,保证了基类方法能够向前扩展和向后兼容,当然类似的还有override修饰符。借此,我们来看一段代码,以及他们的输出,来比较下new和override的区别。 View Code运行结果:ABab====================aB我们来分析一下结果。a1.Print()->A, a1.Print2()->B, b1.Print()->a, b2.Print2()->b,这些都很好理解。当我们把子类赋值给父类是,这里执行了隐式转换。为什么可以隐式转换,原因很简单,因为当你初始化一个子类对象时,其中也包含了父类的所有字段。a2.Print()->a,是因为override重写了父类的Print方法,当父类变量再次调用Print方法时,调用的就是重写之后的,故显示a。a2.Print2()->B,但是new不一样,要是以父类对象调用,依然还是原来的Print2,但是当你使用子类对象调用Print2时,就会是new出来的Print2,显示b。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 A a1 = new A(); 6 B b1 = new B(); 7 a1.Print(); 8 a1.Print2(); 9 b1.Print(); 10 b1.Print2(); 11 Console.WriteLine("====================="); 12 A a2 = b1; 13 // B b2 = (B)a1; 运行时报错,不能转换. 14 a2.Print(); 15 a2.Print2(); 16 } 17 } 18 19 class A 20 { 21 public virtual void Print() 22 { 23 Console.WriteLine("A"); 24 } 25 26 public void Print2() 27 { 28 Console.WriteLine("B"); 29 } 30 } 31 32 class B : A 33 { 34 public override void Print() 35 { 36 Console.WriteLine("a"); 37 } 38 39 public new void Print2() 40 { 41 Console.WriteLine("b"); 42 } 43 }
- 作为约束,用于在泛型声明中约束可能用作类型参数的参数类型。它约束指定泛型类型声明中的任何类型都必须有公共无参构造函数。
base和this:
- base,用于调用基类已被重写的方法,制定创建派生类实例时,应调用基类构造函数。
- this, 限定被相似的名称隐藏的对象,将对象作为参数传递到其他方法,声明索引器。 View Code这里说一下实例化的顺序,实例化过程首先要实例化基类,并依次类推,一直实例化到System.Object为止。所以可以说,实例化总是从System.Object.Object()开始。
1 public string this[int param] 2 { 3 get{ return array[param];} 4 set{array[param] = value;} 5 }
lock:
一看到lock关键字,我们就会想到多线程。为了防止多个线程同时访问一个资源对象而产生的不可预期的结果,我们可以使用lock,但是lock不是唯一解决这个问题的技术。同步技术有:lock语句、监视器、同步事件和等待句柄、Mutex对象。lock的本质,当使用ILDasm查看时,你会发现,其实lock是一个使用System.Threading.Monitor类的try-finally语句。String类型对象对多线程操作是安全的。
就到这里吧。自用,谢绝转载。2012-03-15