C# 为什么编译器在父类中查找方法
我遇到错误,parent不包含“Print”的定义,并且找不到接受第一个参数类型为“parent”的扩展方法“Print”(是否缺少using指令或程序集引用?)C# 为什么编译器在父类中查找方法,c#,asp.net,.net,C#,Asp.net,.net,我遇到错误,parent不包含“Print”的定义,并且找不到接受第一个参数类型为“parent”的扩展方法“Print”(是否缺少using指令或程序集引用?) 这就是多态性的作用。您声明p1,因此: parent p1 = new child(); 因此,您对p1的引用是作为parent的一个实例。该类不包含Print()的定义,因此该行出现错误: p1.Print(); 如果将声明行更改为以下之一: var p1 = new child(); 或 然后,当您作为child的实例访问p
这就是多态性的作用。您声明
p1
,因此:
parent p1 = new child();
因此,您对p1
的引用是作为parent
的一个实例。该类不包含Print()
的定义,因此该行出现错误:
p1.Print();
如果将声明行更改为以下之一:
var p1 = new child();
或
然后,当您作为child
的实例访问p1
时,错误将消失
或者,您可以在parent
中声明Print
,并在child
中重写它:
public class parent
{
public virtual void Print() { // do something }
}
public class child : parent
{
public override void Print() { // do something else }
}
编译器是正确的:
parent
类没有方法Print
的定义。即使分配给p1
的对象具有打印
,编译器也无法从p1
的声明中知道它,并且不允许使用初始值设定项来计算它
为了帮助编译器执行您希望它执行的操作,您需要执行以下操作之一:
parent
一个虚拟方法Print
,其签名与child
中的签名相同,并将override
添加到child
中的定义中Print
方法的接口,并使parent
实现它p1
类型为child
p1
的显式强制转换添加到child
p1
类型为dynamic
如果采用方法1、2、3或4,C#将能够在编译时检查
p1
对象上是否存在Print
。如果采用方法5,编译器将把检查推迟到运行时,此时CLR必须对Print
方法执行额外的搜索,并调用它或抛出运行时错误。当我写入父p1=new child()时,我的理解是p1只是一个引用变量,它指向实际的子类对象。所以如果我这么说,那么p1不是父对象,而是子对象……那么为什么它是父类呢method@BhuwanPandey,它指向子实例,但它被引用为父对象。因此,在本例中,您仅限于在父级中声明的方法。理解为什么会出现这种情况会让你理解多态性:)谢谢Dave,但实际上如果我们写child c=new child(),这里是c--它是一个引用变量,在堆栈上分配了内存……现在new child()将实际创建一个对象,并在堆上分配内存……这里,堆栈上的c引用变量指向在堆上创建的子对象。现在,如果我取parent p1=new child(),这里的p1引用变量也将只指向子对象……那么new child()怎么会出现呢将创建一个父对象…………我完全搞糊涂了我对父对象p1=新子对象()感到困惑;p1.Print();父级p2=新父级();p2.Print();非常感谢这真的很有意义…非常好的解释…非常感谢。非常感谢如果您采用方法5,编译器将延迟检查到运行时,此时CLR将不得不对Print方法执行额外的搜索,并调用它或抛出运行时错误…我没有意识到这一点,这真的很好。
child p1 = new child();
public class parent
{
public virtual void Print() { // do something }
}
public class child : parent
{
public override void Print() { // do something else }
}