Why does this work? Method overloading + method overriding + polymorphism(为什么这行得通?方法重载+方法覆盖+多态)
问题描述
在以下代码中:
public abstract class MyClass
{
public abstract bool MyMethod(
Database database,
AssetDetails asset,
ref string errorMessage);
}
public sealed class MySubClass : MyClass
{
public override bool MyMethod(
Database database,
AssetDetails asset,
ref string errorMessage)
{
return MyMethod(database, asset, ref errorMessage);
}
public bool MyMethod(
Database database,
AssetBase asset,
ref string errorMessage)
{
// work is done here
}
}
其中 AssetDetails 是 AssetBase 的子类.
where AssetDetails is a subclass of AssetBase.
为什么第一个 MyMethod 在运行时在传递 AssetDetails 时调用第二个,而不是陷入无限的递归循环?
Why does the first MyMethod call the second at runtime when passed an AssetDetails, rather than getting stuck in an infinite loop of recursion?
推荐答案
C# 将解析您对其他实现的调用,因为调用对象上的方法,该对象的类有自己的实现将优于覆盖或继承一个.
C# will resolve your call to your other implementation because calls to a method on an object, where the class for that object has its own implementation will be favored over an overridden or inherited one.
这可能会导致微妙且难以发现的问题,就像您在此处展示的那样.
This can lead to subtle and hard-to-find problems, like you've shown here.
例如,试试这段代码(先阅读它,然后编译并执行它),看看它是否符合您的预期.
For instance, try this code (first read it, then compile and execute it), see if it does what you expect it to do.
using System;
namespace ConsoleApplication9
{
public class Base
{
public virtual void Test(String s)
{
Console.Out.WriteLine("Base.Test(String=" + s + ")");
}
}
public class Descendant : Base
{
public override void Test(String s)
{
Console.Out.WriteLine("Descendant.Test(String=" + s + ")");
}
public void Test(Object s)
{
Console.Out.WriteLine("Descendant.Test(Object=" + s + ")");
}
}
class Program
{
static void Main(string[] args)
{
Descendant d = new Descendant();
d.Test("Test");
Console.In.ReadLine();
}
}
}
请注意,如果您将变量的类型声明为 Base 而不是 Descendant 类型,则调用将转到另一个方法,请尝试更改此行:
Note that if you declare the type of the variable to be of type Base instead of Descendant, the call will go to the other method, try changing this line:
Descendant d = new Descendant();
到这里,然后重新运行:
to this, and re-run:
Base d = new Descendant();
那么,那么,您将如何真正设法调用 Descendant.Test(String)?
So, how would you actually manage to call Descendant.Test(String) then?
我的第一次尝试是这样的:
My first attempt looks like this:
public void Test(Object s)
{
Console.Out.WriteLine("Descendant.Test(Object=" + s + ")");
Test((String)s);
}
这对我没有好处,而是一次又一次地调用 Test(Object) 以导致最终的堆栈溢出.
This did me no good, and instead just called Test(Object) again and again for an eventual stack overflow.
但是,以下工作.因为,当我们将 d 变量声明为 Base 类型时,我们最终调用了正确的虚拟方法,我们也可以使用这个技巧:
But, the following works. Since, when we declare the d variable to be of the Base type, we end up calling the right virtual method, we can resort to that trickery as well:
public void Test(Object s)
{
Console.Out.WriteLine("Descendant.Test(Object=" + s + ")");
Base b = this;
b.Test((String)s);
}
这将打印出来:
Descendant.Test(Object=Test)
Descendant.Test(String=Test)
您也可以从外部执行此操作:
you can also do that from the outside:
Descendant d = new Descendant();
d.Test("Test");
Base b = d;
b.Test("Test");
Console.In.ReadLine();
将打印出相同的内容.
但是首先你需要意识到问题,这完全是另一回事.
But first you need to be aware of the problem, which is another thing completely.
这篇关于为什么这行得通?方法重载+方法覆盖+多态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么这行得通?方法重载+方法覆盖+多态
基础教程推荐
- 全局 ASAX - 获取服务器名称 2022-01-01
- 从 VS 2017 .NET Core 项目的发布目录中排除文件 2022-01-01
- 错误“此流不支持搜索操作"在 C# 中 2022-01-01
- 是否可以在 asp classic 和 asp.net 之间共享会话状态 2022-01-01
- JSON.NET 中基于属性的类型解析 2022-01-01
- 首先创建代码,多对多,关联表中的附加字段 2022-01-01
- 将事件 TextChanged 分配给表单中的所有文本框 2022-01-01
- 如何动态获取文本框中datagridview列的总和 2022-01-01
- 在 VS2010 中的 Post Build 事件中将 bin 文件复制到物 2022-01-01
- 经典 Asp 中的 ResolveUrl/Url.Content 等效项 2022-01-01
