本文介绍了为什么这项工作?方法重载+方法重载+多态性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码:

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.

为什么当传递的AssetDetails,而不是陷在递归一个无限循环做的第一的MyMethod致电运行第二个?

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();
        }
    }
}

请注意,如果你声明变量的类型为类型基本而不是后代中,呼叫将转到其他方法,尝试改变该行:

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(字符串) ?然后

我的第一次尝试是这样的:

My first attempt looks like this:

public void Test(Object s)
{
    Console.Out.WriteLine("Descendant.Test(Object=" + s + ")");
    Test((String)s);
}

这确实我没有好,而是直接叫测试(对象)连连最终堆栈溢出。

This did me no good, and instead just called Test(Object) again and again for an eventual stack overflow.

但是,下面的工作。因为,当我们声明 D 变量是基本键入,我们最终调用正确的虚方法,我们可以采取的挂羊头卖狗肉,以及:

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();



将打印出来的一样。

will print out the same.

但是的第一个的您需要注意的问题,这是另一回事完全的。

But first you need to be aware of the problem, which is another thing completely.

这篇关于为什么这项工作?方法重载+方法重载+多态性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 04:27