C# .net根据类型选择了错误的调用方法

C# .net根据类型选择了错误的调用方法,c#,overloading,derived-class,C#,Overloading,Derived Class,我有两个数据类:BaseDataClass和DerivedDataClass,它源自第一个数据类。 我还有两个消费类:ConsumingBaseClass和ConsumingDerivedClass,它源自第一个消费类。 在ConsumingBaseClass中,我有一个虚拟方法DoWork,它接受派生的数据类,并做一些工作 在ConsumingDelivedClass中,我有方法DoWork的覆盖,还有接受BaseDataClass的DoWork的重载。 当我尝试调用DoWork时,传递Der

我有两个数据类:BaseDataClassDerivedDataClass,它源自第一个数据类。 我还有两个消费类:ConsumingBaseClassConsumingDerivedClass,它源自第一个消费类。 在ConsumingBaseClass中,我有一个虚拟方法DoWork,它接受派生的数据类,并做一些工作

ConsumingDelivedClass中,我有方法DoWork的覆盖,还有接受BaseDataClass的DoWork的重载。 当我尝试调用DoWork时,传递DerivedDataClass的实例时,DoWork(BaseDataClass)被调用,而不是DoWork(DerivedDataClass)

有人知道为什么调用了错误的方法吗?

以下代码演示了该问题:

class Program
{
    private static void Main(string[] args)
    {
        ConsumingDerivedClass x = new ConsumingDerivedClass();
        // Wrong DoWork is called - expected calling of DoWork(DerivedDataClass) but actually called DoWork(BaseDataClass)
        x.DoWork(new DerivedDataClass());
        Console.ReadKey();
    }
}

public class ConsumingBaseClass
{
    public virtual void DoWork(DerivedDataClass instance)
    {
        Console.WriteLine("ConsumingBaseClass.DoWork(DerivedDataClass); Type of argument is '{0}'", instance.GetType());
    }
}

public class ConsumingDerivedClass : ConsumingBaseClass
{
    public override void DoWork(DerivedDataClass instance)
    {
        Console.WriteLine("ConsumingDerivedClass.DoWork(DerivedDataClass); Type of argument is '{0}'", instance.GetType());
        base.DoWork(instance);
        // Some additional logic
    }

    public void DoWork(BaseDataClass instance)
    {
        Console.WriteLine("ConsumingDerivedClass.DoWork(BaseDataClass); Type of argument is '{0}'", instance.GetType());
        DerivedDataClass derivedInstance = new DerivedDataClass();
        // Some logic based on what is in baseInstacne
        derivedInstance.SomeProperty = "Value, got from some logic";

        base.DoWork(derivedInstance);
        // Some additional logic
    }
}

public class BaseDataClass
{ }

public class DerivedDataClass : BaseDataClass
{ 
    public string SomeProperty { get; set; } 
}
有人知道为什么调用了错误的方法吗

根据语言规范调用正确的方法。是你的期望错了

在ConsumingDelivedClass中,我有方法DoWork的重写,也有接受BaseDataClass的DoWork的重载

基本上,这就是问题所在。超负荷解决方案并不像你想象的那样有效。编译器从调用目标的编译时类型开始工作,通过基类向上到
对象
。只考虑新声明(甚至未重写)的方法

您可以通过以下方式更改将使用的重载:

((ConsumingBaseClass) x).DoWork(new DerivedDataClass());
理想的情况是,如果你有这么脆弱的东西,给这些方法取不同的名字是值得的。重载应该具有相同的效果,只是以不同的方式提供信息

基本上,看看我的第一个问题,以及第一个答案的细节。我还有一本书,你可能会觉得很有用

有人知道为什么调用了错误的方法吗

根据语言规范调用正确的方法。是你的期望错了

在ConsumingDelivedClass中,我有方法DoWork的重写,也有接受BaseDataClass的DoWork的重载

基本上,这就是问题所在。超负荷解决方案并不像你想象的那样有效。编译器从调用目标的编译时类型开始工作,通过基类向上到
对象
。只考虑新声明(甚至未重写)的方法

您可以通过以下方式更改将使用的重载:

((ConsumingBaseClass) x).DoWork(new DerivedDataClass());
理想的情况是,如果你有这么脆弱的东西,给这些方法取不同的名字是值得的。重载应该具有相同的效果,只是以不同的方式提供信息


基本上,看看我的第一个问题,以及第一个答案的细节。我还有一个您可能会发现很有用的方法。

尝试更改基本方法以使用BaseDataClass并重写它。提供衍生数据特定版本作为“新”方法(根据@Jon Skeet的回答)


尝试更改基本方法以使用BaseDataClass并重写它。提供衍生数据特定版本作为“新”方法(根据@Jon Skeet的回答)