C#-在构造函数或析构函数中调用的虚拟函数的行为
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C#-在构造函数或析构函数中调用的虚拟函数的行为,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2591字,纯文字阅读大概需要4分钟。
内容图文
![C#-在构造函数或析构函数中调用的虚拟函数的行为](/upload/InfoBanner/zyjiaocheng/655/f22821951c694fc881a262dda1ff60b0.jpg)
我已经阅读了一些有关虚拟函数在c和c#之间的构造函数或析构函数中调用的不同行为的材料.然后,我测试以下代码,以确认c#可以调用虚拟派生的虚拟函数,因为其对象存在于构造函数之前.但是我发现结果与c中的类似代码相同.谁能告诉我为什么C#不能显示“ 22”而只能显示“ 12”的原因.
C#代码
public class Base
{
public Base() { fun(); }
public virtual void fun() { Console.WriteLine(1); }
}
public class Derived : Base
{
public Derived() { fun(); }
public virtual void fun() { Console.WriteLine(2); }
}
C代码
class Base
{
public:
Base(){fun();}
virtual void fun(){cout<<1;}
};
class Derived : Base
{
public:
Derived(){fun();}
virtual void fun(){cout<<2;}
};
c和C#的输出结果均为“ 12”.
解决方法:
您的C#代码中有错误.
要覆盖C#函数,您必须指定override关键字.
如果您再次编写virtual,则会使基本功能蒙上阴影,但是如果没有new关键字,您应该得到警告.
如果两个都声明为虚拟,则两个函数的名称相同!
让我们举个例子…
public class Base
{
public Base() { fun(); }
public virtual void fun() { Console.Write(1); }
}
public class Derived : Base
{
public Derived() { fun(); }
public override void fun() { Console.Write(2); }
}
public class DerivedWithError : Base
{
public DerivedWithError() { fun(); }
public new virtual void fun() { Console.Write(3); }
}
...
// This will print "22".
Base normal = new Derived();
Console.WriteLine();
// This will print "13" !!!
Base withError = new DerivedWithError ();
Console.WriteLine();
// Let's call the methods and see what happens!
// This will print "2"
normal.fun();
Console.WriteLine();
// This will print "1" !!!
withError.fun();
Console.WriteLine();
阴影表示“添加相同名称的新方法而不使用多态性”.
如果没有override关键字,您将禁用多态性.
因此,现在一切都应该干净并且易于理解.
DerivedWithError.fun()是一个全新的虚拟方法.它与基类中的fun函数具有相同的名称,但它们没有关联!
从虚拟表(或虚拟方法表,如果您更喜欢使用其他名称)的角度来讲,基本函数和派生函数的阴影会遮盖虚拟表中的两个不同条目,即使它们具有相同的名称也是如此.
如果改用override,则将强制派生类中的func方法覆盖Base.func占用的虚拟表项,这是多态性.
危险,但.NET允许,请务必谨慎使用语法!
您可以在C#中的构造函数中调用虚拟函数,但是通常在派生类中,如果在基本构造函数中调用了方法,则在使用派生类中的字段时应格外小心.
现在,为了简洁起见,避免混乱和风险,您应该避免在构造函数中调用虚拟方法,但实际上,多次使用是非常有用的.
例如,所谓的“工厂方法”不能访问任何变量.
public abstract class MyClass
{
public IList<string> MyList { get; private set; }
public MyClass()
{
this.MyList = this.CreateMyList();
}
protected abstract IList<string> CreateMyList();
}
public class MyDerived : MyClass
{
protected override IList<string> CreateMyList()
{
return new ObservableCollection<string>();
}
}
这是完全合法的,并且有效!
内容总结
以上是互联网集市为您收集整理的C#-在构造函数或析构函数中调用的虚拟函数的行为全部内容,希望文章能够帮你解决C#-在构造函数或析构函数中调用的虚拟函数的行为所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。