【发布时间】:2015-12-22 04:02:02
【问题描述】:
上周我遇到了一个有趣的问题,我不确定我是否真正理解following code 的多态性。我根据自己编写的一些代码创建了这个示例。
基本设置
- 我有一个知道如何训练动物的“训练师”课程。
- 我将它用作基类并创建了一个子类“DogTrainer”,它只知道如何训练狗。
- 我使用超类作为返回类型创建了一个函数指针。
- 然后我调用该函数来获取子类“DogTrainer”的新实例。
- 然后我调用从函数指针返回的实例的“Train”方法。
- “Train”方法调用“Trainer”-“Train”方法而不是“DogTrainer”-“Train”方法,如预期的那样
这里是代码
// Does not work as expected
// Calls the Trainer Train not the DogTrainer Train
var getTrainer = new Func<Trainer>(() => new DogTrainer(new Dog()));
var funcTrainer = getTrainer();
Console.WriteLine(funcTrainer.Train());
现在,如果我使用接口作为返回类型,它会按预期“IF”工作,我将接口直接标记在“DogTrainer”子类上
// Works as expected
var getITrainer = new Func<ITrainer>(() => new DogTrainer(new Dog()));
var funcITrainer = getITrainer();
Console.WriteLine(funcITrainer.Train());
如果我在子类上没有接口,它将无法按预期工作。 See Example
// Does not work as expected
// Calls the Trainer Train not the Dog Trainer Train
var getITrainerWithNoInterface = new Func<ITrainer>(() => new DogTrainerWithNoInterface(new Dog()));
var funcITrainerWithNoInterface = getITrainerWithNoInterface();
Console.WriteLine(funcITrainerWithNoInterface.Train());
如果有人可以让我知道我在这里缺少什么,那么这种行为不是我所期望的。当我在我的代码中发现这个错误时,我能够解决它,我在这里寻找的是“为什么”会发生这种情况。
这里是DogTrainerWithNoInterface,它可能是谜题的主要部分 (Trainer:ITrainer)
public class DogTrainerWithNoInterface : Trainer
{
public DogTrainerWithNoInterface(IAnimal animal)
: base(animal)
{ }
public new string Train()
{
return $"Speak Ubu, Speak : {Animal.Speak()}";
}
}
【问题讨论】:
-
您看到这种行为是因为协变泛型类型,而不是因为多态性
-
这是语言规范中所称的“接口重新实现”的行为。我在一个类似的例子中描述了它here。它与
Func<T>无关,这只会使这里不必要地复杂化。 -
感谢您将问题与良好的紧凑样本放在一起。正如@mikez 指出的那样,大部分问题已经有了很好的答案(链接为重复)。第一个样本被What is shadowing覆盖。
-
感谢您的信息。我知道现在发生了什么。
标签: c# polymorphism func