zoukankan      html  css  js  c++  java
  • 也说new

    也说new

    今天看到了Anytao的[你必须知道的.NET] 第五回:深入浅出关键字---把new说透。Anytao这一系列文章写得都非常好,其实甚至正是我一直想写的。比起各种应用层面上的技巧,我更喜欢研究.NET的底层机制。但是光顾了自己研究了,也没好好写东西给大家分享。

    《把new说透》这篇文章介绍的内容不错,但Anytao文字上可能没有表达得很清晰。C# 2.0中关键字new有三种作用——1)作为修饰符覆盖父类中的virtual成员,2)作为运算符创建对象,3)作为泛型类型中对类型形参的约束。

    new的这三种功能其实是完全不相干的,Anders Liu个人感觉作为文章来说,应该完全分开在不同的小节中去介绍。

    1 new修饰符

    new修饰符用于修饰类型成员(属性、方法等)。

    (懒得画图写代码了,所以采用纯文字描述。大家可以看Anytao的代码)

    当父类中编写了virtual方法时,子类出现了相同签名的方法时,必须冠以override或new运算符。

    如果使用override运算符,则可以实现“多态”。即:将子类对象转成父类型后,调用virtual方法,实际上执行的是子类中的方法代码。

    而如果使用new运算符,则不会出现上述情况,将子类对象转成父类型后,调用virtual方法,实际上执行的是还是父类中的方法代码。

    2 new运算符

    new运算符用于创建对象。当使用new运算符创建对象时,会发生下列事情:

    - 根据元数据中的类型信息,计算对象所需空间,根据值类型/引用类型的区别,在栈或者堆中开辟适当大小的存储区域。
    - 根据元数据中的类型信息,对类成员空间进行排列。并初始化成员。(*)
    - 调用构造器。
    - 返回对象引用。

    所以,string s = new string("asdf");实际上是首先根据string类型信息在堆上开辟存储空间,排列其成员,然后调用string(string s)签名的构造器,最后返回新对象引用,并通过等号赋给变量s。

    因此,Anytao提到的int i与int i = new int()的区别也就出来了。

    但这里Anytao没有陈述清楚的是,int i出现的位置——int i即可以出现在类中,成为一个字段(域);也可以出现在方法中,成为一个变量(还有一种是出现在方法参数中,但就其语义,和变量是类似的)。

    如果int i是一个字段(域)定义,那么两者是没有任何区别的。因为,注意上面第二条带(*)的部分,当客户代码初始化当前类的对象时,会同时初始化这个i,将其值置为0。

    如果int i是一个变量定义,那么,int i只是声明了一个局部变量,此时的i不能直接使用,必须首先赋值(如果未赋值就使用,会得到一个编译错误)。而int i = new int()则对i进行了一个初始化。

    3 new约束

    在泛型类型定义时,可以使用where指定一些约束,其中一种就是new约束。new 约束要求用作类型实参的类型必须带有公共无参构造器。如class A<T> where T : new();这里只有带有公共无参构造器的类型才能用作T。

    需要注意两点,1)如果同时存在其他约束,那么new约束应该是最后一个。2)不能用new(int i)的形式来约束拥有指定签名的构造器。

    好了,希望Anders Liu能给Anytao梳理一下文字。

  • 相关阅读:
    Apache Mahout
    ganglia安装
    编译出错 recompile with -fPIC
    centos6.4 基本安装nagios
    HDU1285 确定比赛名次
    HDU2888 Check Corners(二维RMQ)
    HDU3183 A Magic Lamp
    HDU1711 Number Sequence(KMP模版题)
    HDU3694 Fermat Point in Quadrangle(求四边形费马点)
    POJ2155 Matrix(二维树状数组)
  • 原文地址:https://www.cnblogs.com/winner/p/732994.html
Copyright © 2011-2022 走看看