请注意,类总是在堆上创建的,当出现函数调用,赋值时候,.NET总是传值,所不同的是,传递的是引用的值,结构也是传值,确是传递结构本身。但结构成员仍然遵循按值传递原则。请勿误解传引用和传值。凡是涉及类之间操纵的,包括赋值,函数调用等等一切行为,地址定位都是通过堆栈运算操纵的,但记住,堆栈中并不保存类的任何信息。一个类一旦创建,那么他在堆内存上就是只读的,不许在应用程序生存期中被破坏,除非你显示调用Fianlize()方法或者CLR破坏它。记住一点,非原始值类型,都是存放在堆中,所以,当你用一个类包装一个int类型的数据时,这个int数据就代表着堆上的一个32位内存空间。与堆栈半点关系也没有。
重写是多态的概念,它复写了基类方法,是晚绑定的。隐藏方法是使用new关键字创建了一个新的方法,C#对非虚方法使用早绑定,所以隐藏了基类方法--这就是“隐藏”的本质。

解决方案 »

  1.   

    关于堆栈和堆的问题,好像c#的托管机制,并不要求程序员知道内存是如何分配的除非你用到不安全代码,才有必要知道它们是如何排布的——那个时候,可以用tructLayoutAttribute类来要求那些是如何排布的!关于重写和隐藏:
    override的要求比较严格,不但要是virtual类型,参数格式要一致,访问权限,也要一样!
     而new就比较随便了——当然,有时候,多加、少加一个new,它会警告你! 我觉得,new关键字,是给程序员自己看的,没有其他意义,只是说明,基类有过这个东西而已!和全局变量被局部屏蔽一样,只不过是基类函数,被派生类函数屏蔽了而已!
    当然,还可以用base.*的方法,去访问基类函数的!new关键字,是给程序员自己看的,没有其他意义,只是说明,基类有过这个东西而已!和全局变量被局部屏蔽一样,只不过是基类函数,被派生类函数屏蔽了而已!
    当然,还可以用base.*的方法,去访问基类函数的! new的作用,只是给程序员一点提醒而已,好像既不会起到动态联编的作用,又不会起到完全屏蔽基类的作用!
     所以它多加一个,少加一个,都一样可以通过编译——比如你基类,没有子类同样的函数,你一样可以加个new字的,而如果你基类有和子类同样的函数,你也同样可以不加new字的!而重写,主要是为多态的要求而制定的,系统开销会高一些!
      

  2.   

    属性在dotNET内部是以“成员方法”的形式实现的,它本身就是一种方法,只不过CLR为它提供固有支持,是给你的一种“语法甜头”,没什么大用!
      

  3.   

    To  daou101(海天一鸥) :
    也就是说在堆栈中存放的都是类的引用,能不能举个例子说明一下,我还是不大明白!To  ncucf(ncu晨风)
    也就是说覆盖和隐藏都差不多,而声明了虚函数还要增加系统开销,那为什么还要用virtual和override~~不如new方便,他们的功能都是一样的!
      

  4.   

    我说了是为了动态联编的作用啊!
    比如一个父类的类型参数,如果是用new的方法,那不管传什么引用给它,只会是派生类的方法被执行。
    而用了虚函数,也就是可以override的,你给他一个派生类对象的引用,它就执行派生类的方法,给了一个基类对象的引用,它就执行基类的方法,这就可以起到一个运行过程中,自动识别的功能啊!
      

  5.   

    非常简单的例子:
    Main()
    {
     int a=11;
     //a存储在堆栈中,它是零时变量
     foo(a);//传递a的一份拷贝,也就是在函数调用堆栈上申请了的一个32位内存区,值是11
     //a被释放了
     //函数调用结束了,堆栈中的a的副本自动消失了,因为出栈了  如果是对象,那么传递的就是引用。道理一样。
    }void foo(int a)
    {
      a++;
      Console.WriteLine(a);
    }
      

  6.   

    to daou101(海天一鸥):
    方法中的变量存放在堆栈中,那他怎样和堆中的数据联系?