代码改变世界

《你必须知道的.NET》读后小结(3)

2012-03-15 21:43  Oliver_Zhao  阅读(152)  评论(0编辑  收藏  举报

  今天,我们来回顾一下C#中的一些关键字,并深入理解一下他们。然后聊一下C#中容易引起混淆的一些东西,我们来看一下书中对它们的解释。2012-03-15

new:

 我们从多方面讨论new。

  • 作为运算符,用于创建对象和调用构造函数。这是我们最常用的,比方说Object a = new Object();。它在内存中到底做了什么,我们在这里就不深究了。
  • 作为修饰符,用于向基类成员隐藏继承成员。这主要是针对版本控制而言,保证了基类方法能够向前扩展和向后兼容,当然类似的还有override修饰符。借此,我们来看一段代码,以及他们的输出,来比较下new和override的区别。
    View Code
     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 }
    运行结果:
    A
    B
    a
    b
    ====================
    a
    B
    我们来分析一下结果。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。
  • 作为约束,用于在泛型声明中约束可能用作类型参数的参数类型。它约束指定泛型类型声明中的任何类型都必须有公共无参构造函数。

base和this:

  • base,用于调用基类已被重写的方法,制定创建派生类实例时,应调用基类构造函数。
  • this, 限定被相似的名称隐藏的对象,将对象作为参数传递到其他方法,声明索引器。
    View Code
    1 public string this[int param]
    2 {
    3 get{return array[param];}
    4 set{array[param] = value;}
    5 }
    这里说一下实例化的顺序,实例化过程首先要实例化基类,并依次类推,一直实例化到System.Object为止。所以可以说,实例化总是从System.Object.Object()开始。

lock:

一看到lock关键字,我们就会想到多线程。为了防止多个线程同时访问一个资源对象而产生的不可预期的结果,我们可以使用lock,但是lock不是唯一解决这个问题的技术。同步技术有:lock语句、监视器、同步事件和等待句柄、Mutex对象。lock的本质,当使用ILDasm查看时,你会发现,其实lock是一个使用System.Threading.Monitor类的try-finally语句。String类型对象对多线程操作是安全的。

 

就到这里吧。自用,谢绝转载。2012-03-15