日期:2014-05-18  浏览次数:20791 次

我遇到一个有趣的问题!!大家进来看看!!尼玛????
如果看完问题你想这样回答:
1.首先是检查父有没有这样的方法然后才会检查子类有没有怎样的方法。那你就不用留言了!!
2.如果你竟然在回答我栈和堆是怎么样一回事的,那你也不用留言了!!因为栈和堆我懂!!
3.如果你刚写完代码的和心里有问题的哪你也不用留言了,因为你累了!!

以下我的问题:


------解决方案--------------------
当然是调用person.go方法,这和是堆和栈没什么关系,和编译器有关系,编译器可以决定如何调用go方法,如果go是virtual/override方法,那么编译器会这样调用go,到p引用的对象也就是china对象中查询签名为go的方法然后调用它,

如果go不是virtual/override方法,那么编译器根本不会去查询p引用什么对象,直接就调用person.go方法,编译器知道如何调用任何一个类的任何签名的方法,不需要到p引用对象中查询这个方法,直接调用person.go方法对编译器来说更容易做到,编译器只是检查一下p的类型,是person,然后就直接在typeof(Person)中找到签名为go的方法,根本就没有查找p指向的实例,


------解决方案--------------------
简单的说,调用哪个类的方法,取决于这个方法是否是virtual/override方法,和队以及栈没有关系,

关键的一点是,编译器不需要去检查p指向的实例就可以调用go的方法,因为编译器可以通过typeof(Person)取得Type对象,在Type对象就可以找到go方法,所以它无需检查p指向哪个类的实例,就可以调用go方法,这样调用反而更快,
------解决方案--------------------
lL已经完整地说清楚了。

但是我还想说几句,看下面的代码:
C# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace ConsoleApplication3
{
    class Program
    {
        static int i = 3;
        static void Main(string[] args)
        {
            int i = 4;
            Console.WriteLine(i);
            Console.WriteLine(Program.i);
        }
    }
}

------解决方案--------------------
java默认成员函数都是虚函数,而c#默认成员函数为非虚函数 
 C# new 
C# code

 public class ClassA
    {
        public void A(){}
    }
    public class DeriveclassA:ClassA
    {
        public new void A() {}
    }