使用Func<;T>;在C#中
本文关键字:gt lt 使用 Func | 更新日期: 2023-09-27 18:27:42
上周我遇到了一个有趣的问题,我不确定我是否真正理解以下代码的多态性。我基于自己编写的一些代码创建了这个示例。
基本设置
- 我有一个班"驯兽师",知道如何训练动物
- 我用它作为基类,并创建了一个子类"DogTrainer",它知道如何只训练狗
- 我使用超类作为返回类型创建了一个函数指针
- 然后我调用这个函数,得到子类"DogTrainer"的一个新实例
- 然后,我调用从函数指针返回的实例的"Train"方法
- "训练"方法调用"训练器"-"训练"法,而不是预期的"DogTrainer"-"培训"法
这是代码
// 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());
如果我在子类上没有接口,它就不能按预期工作。参见示例
// 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()}";
}
}
注意:这个答案纯粹是为了描述由于不适合注释而出现的"新"问题。请忽略投票,因为它不能完全回答他的问题
OP链接中的样本:
public class DogTrainer : Trainer, ITrainer
{
public DogTrainer(IAnimal animal)
: base(animal)
{ }
public new string Train()
{
return $"Speak Ubu, Speak : {Animal.Speak()}";
}
}
在声明方法/属性时不要使用new
。在底座上制作virtual
,然后制作override
。你正在做的是将方法隐藏在你的基础上。
您只能在使用特定类型(DogTrainer
)时调用new
方法。对基的任何向下转换都将调用它的方法,即使用声明为Trainer
或ITrainer
的变量。
知道何时使用覆盖和新关键字(C#编程指南)