为什么编译器会查找父类中的方法

时间:2015-05-23 17:04:45

标签: c# asp.net .net

我得到错误,父母'不包含' Print'的定义没有扩展方法' Print'接受第一个类型为'父母'可以找到(你错过了使用指令或程序集引用吗?)

    class Program
    {
        public static void Main(string[] args)
        {
            parent p1 = new child();
            p1.Print();
        }
    }
    //Parent Class
    public class parent
    {
    }

    //Child Class
    public class child : parent
    {
        public void Print() { }
    }

2 个答案:

答案 0 :(得分:1)

这是行动中的多态性。你声明p1

parent p1 = new child();

因此,您对p1的引用是parent的实例。该课程不包含Print()的定义,因此错误就行:

p1.Print();

如果您将声明行更改为以下之一:

var p1 = new child();

child p1 = new child();

然后,当您作为p1的实例访问child时,错误就会消失。

或者,您可以在Print中声明parent并在child中覆盖它:

public class parent
{
    public virtual void Print() { // do something }
}

public class child : parent
{
    public override void Print() { // do something else }
}

答案 1 :(得分:1)

编译器是正确的:parent类没有方法Print的定义。即使分配给p1的对象确实有Print,编译器也无法从p1的声明中知道它,并且不允许使用初始化程序来计算它进行。

为了帮助编译器按照您的意愿执行操作,您需要执行以下操作之一:

  1. parent 虚拟方法Print提供与child中相同的签名,并将override添加到{{1}中的定义中1}}
  2. 声明具有child方法的接口,并使Print实现它
  3. 声明parent
  4. 类型的p1
  5. 在拨打电话前向child添加p1的明确演员
  6. 声明child类型的p1
  7. 如果采用方法1,2,3或4,C#将能够在编译时检查dynamic对象上是否存在Print。如果采用方法5,编译器会将检查推迟到运行时,此时CLR必须执行p1方法的额外搜索,并调用它或抛出运行时错误。