Tre*_*vor 12 c# virtual-functions
是否可以确定是否已覆盖虚拟方法:
class ABase {
public void DoSomething(object p)
{
p.Process();
if( /* DoSomethingExtra is implemented */ )
DoSomethingExtra(p);
}
public virtual void DoSomethingExtra(object p) { }
}
class ADerived {
public override void DoSomethingExtra(object p)
{
p.ProcessMore();
}
}
Run Code Online (Sandbox Code Playgroud)
我意识到这个例子看起来很愚蠢(例如,你为什么不调用DoSomethingExtra(),因为它没有做任何事情).我向你保证,我有一个合法的案例.有任何想法吗?
Ree*_*sey 10
所以在C#中可以声明一个虚方法而不实现它.
这是不可能的.您可以将方法声明为抽象,但如果该方法是虚拟的,则它将具有一些实现(即使实现实际上是空操作).
上面的代码报告错误Error 1 'ABase.DoSomethingExtra(object)' must declare a body because it is not marked abstract, extern, or partial.
处理此问题的典型方法是使用null op实现声明方法,并调用它:
class ABase {
public void DoSomething(object p)
{
p.Process();
DoSomethingExtra(p); // Always call
}
public virtual void DoSomethingExtra(object p)
{
// Do nothing here
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:既然您的问题已被编辑,我会为您提供与您的编辑相关的更多信息,特别是:
我意识到这个例子看起来很愚蠢(例如,你为什么不调用DoSomethingExtra(),因为它没有做任何事情).我向你保证,我有一个合法的案例.有任何想法吗?
没有直接的方法来确定当前实例是否覆盖了您的虚方法.这可能需要一些非常讨厌,不可维护的代码,例如通过反射检查方法体声明类型,看看有什么.
话虽如此,我强烈质疑这里的设计目标.你的问题基本上是要求一种违反Liskov替代原则的特定方式,这是面向对象编程的核心原则之一.这将使您的代码性能降低,维护更少......
反思是一个很好的答案。
using System.Reflection;
Type classType = typeof(ADerived);
MethodInfo method = classType.GetMethod("DoSomethingExtra");
if (method.DeclaringType == typeof(ABase))
Console.WriteLine("DoSomethingExtra not overridden.");
else
Console.WriteLine("DoSomethingExtra is overridden by " + method.DeclaringType.Name);
Run Code Online (Sandbox Code Playgroud)
我希望您会发现这个有用。
一旦实现了特殊的对象查看器,当对象未知时,除非没有被覆盖,否则我将使用ToString()。
检查一下:使用反射检测方法是否被覆盖 (C#)
\n\n反射是在运行时执行此操作的唯一方法。这应该带有一个健康警告,但是,从 OOP 的角度来看,它应该被认为是一个非常糟糕的想法\xe2\x84\xa2 。基类通常不应该知道或关心派生类是如何实现的。
\n