none
new 对象 RRS feed

  • 问题

  • 最近在看CLR VIR C#第四章 类型基础,对这个如何NEW对象不了解,,看过周雪峰

    http://social.msdn.microsoft.com/Forums/zh-CN/2212/thread/125fa4dd-d832-4cb3-97b8-80a6d5b4e0e7

    后,我想了解类型对象指针TypeObjectPtr对应的方法表中方法如何排列的.

    问题1 这个方法表中包括父类的实例方法吗?

    还有个继承的问题,如果B继承于A ,实例化B,B b=new B();的时候,加断点调试后我发现,它是这样运行的,

    B类静态字段,B类静态构造器,

    B类实例字段,B类实例构造器(它没有真正进去),

    A类静态字段,A类静态构造器,

    A类实例字段,A类实例构造器,返回B类实例构造器

    2我很奇怪它的运行顺序,为什么都执行到了B的标签了,而没有进去,跳到A的静态字段去了?

    3它没有走我写的方法,方法是在什么时候被加到方法表里去的.是在编译为dll时候吗?

    3 new B()时候会自动生成1个B类型对象和A类型对象,并初始化它所有字段吗?

    还是仅仅包含1个B类型对象,里面包含了A的内容?

    问题多多,请大家不吝指教.

    2012年3月23日 5:19

答案

  • 你好,

    首先,我们使用到的任何类都继承自System.Object类。 子类在继承父类后,其构造函数理应从子类开始一直追溯到所有的父类,直至System.Object。而对于你的字段,自然要被分配出来,然后再被初始化。更多关于构造方面的说明,可以看看CLR VIA C# 的第八章 方法。 关于静态字段的说明,可以看看第六章 静态类。 会有很详细的介绍。

    2. 在第八章中,尤其是8.3 类型构造器会给你更加全面的指导,你不妨可以先跳过去看看。

    3. 继承在C# 语言规范中是这样被描述的:

    类继承其基类的成员。继承意味着一个类隐式地将它的基类的所有成员当作自已的成员,但基类的实例构造函数、静态构造函数和析构函数除外。派生类能够在继承基类的基础上添加新的成员,但是它不能移除继承成员的定义。

    继承从一定程度上可以说是,子类属于父类,具有父类的某些行为和属性。不妨举个例子:

    有这样的一段代码:

        class Program
        {
            static void Main(string[] args)
            {
    
                B b = new B();
    
            }
    
        }
    
        class A
        {
            int i = 0;
        }
    
        class B : A
        {
            int j = 0;
        }
    当我将这段代码编译后,CLR的代码是怎么个样子呢?
    .method private hidebysig static void  Main(string[] args) cil managed
    {
      .entrypoint
      // Code size       8 (0x8)
      .maxstack  1
      .locals init ([0] class ConsoleApplication1.B b)
      IL_0000:  nop
      IL_0001:  newobj     instance void ConsoleApplication1.B::.ctor()
      IL_0006:  stloc.0
      IL_0007:  ret
    } // end of method Program::Main
    很显然,CLR并没有重新再New一个A类型的实例吧!

    Neddy Ren[MSFT]
    MSDN Community Support | Feedback to us

    • 已标记为答案 Purplesun 2012年3月26日 10:12
    2012年3月26日 8:04
  • 子类继承父类后,子类就具有了父类的某些属性和方法,可以使用Base.Method() 来调用父类的方法。所以我们说子类具有父类的行为。同时,子类还能继承父类的成员属性,因此,也具有了父类的属性。

    但是,如果采用了Sealed关键字,那么就不能被继承,而采用了abstract关键字后,子类还要重新实现父类中的方法。因此我说是从一定程度上,而不是完全绝对。

    当然,在子类中,往往青出于蓝胜于蓝。 子类要重写父类的方法和属性,因此有override。 而当同一个方法在子类中要求脱离父类的继承,要在子类中全新实现的话,我们可以用在方法名中添加new关键字来实现。

    更多内容,请见C# 语言规范。 你可以在你的Visual Studio 安装目录下找到:

    比如说在Visual Studio 2010安装目录下:

    ...\Microsoft Visual Studio 10.0\VC#\Specifications\1033\

    继承的功能很强大,涉及到接口、类....等等。 你可以在C#语言规范文档中查找“继承”来了解详细情况。


    Neddy Ren[MSFT]
    MSDN Community Support | Feedback to us

    • 已标记为答案 Purplesun 2012年3月27日 6:51
    2012年3月27日 2:17

全部回复

  • 你好,

    首先,我们使用到的任何类都继承自System.Object类。 子类在继承父类后,其构造函数理应从子类开始一直追溯到所有的父类,直至System.Object。而对于你的字段,自然要被分配出来,然后再被初始化。更多关于构造方面的说明,可以看看CLR VIA C# 的第八章 方法。 关于静态字段的说明,可以看看第六章 静态类。 会有很详细的介绍。

    2. 在第八章中,尤其是8.3 类型构造器会给你更加全面的指导,你不妨可以先跳过去看看。

    3. 继承在C# 语言规范中是这样被描述的:

    类继承其基类的成员。继承意味着一个类隐式地将它的基类的所有成员当作自已的成员,但基类的实例构造函数、静态构造函数和析构函数除外。派生类能够在继承基类的基础上添加新的成员,但是它不能移除继承成员的定义。

    继承从一定程度上可以说是,子类属于父类,具有父类的某些行为和属性。不妨举个例子:

    有这样的一段代码:

        class Program
        {
            static void Main(string[] args)
            {
    
                B b = new B();
    
            }
    
        }
    
        class A
        {
            int i = 0;
        }
    
        class B : A
        {
            int j = 0;
        }
    当我将这段代码编译后,CLR的代码是怎么个样子呢?
    .method private hidebysig static void  Main(string[] args) cil managed
    {
      .entrypoint
      // Code size       8 (0x8)
      .maxstack  1
      .locals init ([0] class ConsoleApplication1.B b)
      IL_0000:  nop
      IL_0001:  newobj     instance void ConsoleApplication1.B::.ctor()
      IL_0006:  stloc.0
      IL_0007:  ret
    } // end of method Program::Main
    很显然,CLR并没有重新再New一个A类型的实例吧!

    Neddy Ren[MSFT]
    MSDN Community Support | Feedback to us

    • 已标记为答案 Purplesun 2012年3月26日 10:12
    2012年3月26日 8:04
  • dear Neddy Ren,thank you very much ,now i  understand what you say
    2012年3月26日 10:12
  • 对这句话我还有点疑问,

    继承从一定程度上可以说是,子类属于父类,具有父类的某些行为和属性。

    你能告诉我吗?

    2012年3月26日 10:14
  • 子类继承父类后,子类就具有了父类的某些属性和方法,可以使用Base.Method() 来调用父类的方法。所以我们说子类具有父类的行为。同时,子类还能继承父类的成员属性,因此,也具有了父类的属性。

    但是,如果采用了Sealed关键字,那么就不能被继承,而采用了abstract关键字后,子类还要重新实现父类中的方法。因此我说是从一定程度上,而不是完全绝对。

    当然,在子类中,往往青出于蓝胜于蓝。 子类要重写父类的方法和属性,因此有override。 而当同一个方法在子类中要求脱离父类的继承,要在子类中全新实现的话,我们可以用在方法名中添加new关键字来实现。

    更多内容,请见C# 语言规范。 你可以在你的Visual Studio 安装目录下找到:

    比如说在Visual Studio 2010安装目录下:

    ...\Microsoft Visual Studio 10.0\VC#\Specifications\1033\

    继承的功能很强大,涉及到接口、类....等等。 你可以在C#语言规范文档中查找“继承”来了解详细情况。


    Neddy Ren[MSFT]
    MSDN Community Support | Feedback to us

    • 已标记为答案 Purplesun 2012年3月27日 6:51
    2012年3月27日 2:17
  • dear Neddy Ren , i learn a lot from your answer,thank you ~

    hope in the further i can tell to others.

    2012年3月27日 6:50