C# .net根据类型选择了错误的调用方法
我有两个数据类:BaseDataClass和DerivedDataClass,它源自第一个数据类。 我还有两个消费类:ConsumingBaseClass和ConsumingDerivedClass,它源自第一个消费类。 在ConsumingBaseClass中,我有一个虚拟方法DoWork,它接受派生的数据类,并做一些工作 在ConsumingDelivedClass中,我有方法DoWork的覆盖,还有接受BaseDataClass的DoWork的重载。 当我尝试调用DoWork时,传递DerivedDataClass的实例时,DoWork(BaseDataClass)被调用,而不是DoWork(DerivedDataClass) 有人知道为什么调用了错误的方法吗? 以下代码演示了该问题:C# .net根据类型选择了错误的调用方法,c#,overloading,derived-class,C#,Overloading,Derived Class,我有两个数据类:BaseDataClass和DerivedDataClass,它源自第一个数据类。 我还有两个消费类:ConsumingBaseClass和ConsumingDerivedClass,它源自第一个消费类。 在ConsumingBaseClass中,我有一个虚拟方法DoWork,它接受派生的数据类,并做一些工作 在ConsumingDelivedClass中,我有方法DoWork的覆盖,还有接受BaseDataClass的DoWork的重载。 当我尝试调用DoWork时,传递Der
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的回答)