5

我有这样的类层次结构

public abstract class CalendarEventBase{}

public class TrainingEvent : CalendarEventBase{}

public class AuditEvent : CalendarEventBase{}

我想创建一个动作 Action lamda,它有一个 CalendarEventBase 类型的通用类型参数,我可以将它分配给以下不同的方法:

public void EmailCancelation(TrainingEvent trainingEvent)

public void EmailCancelation(AuditEvent auditEvent)

我创建了以下非法分配:

Action<CalendarEventBase> emailCancelation = _trainingService.EmailTrainingCancellation;

编译器抱怨它期望使用 void(CalendarEventBase) 作为签名的方法。我对此感到惊讶,因为我认为它会接受更派生的类型。

为了解决这个问题,我创建了以下委托来完成我的任务:

public delegate void EmailCancelation<in T>(T calendarEvent) where T : CalendarEventBase;

我的问题是,我是否可以在不创建额外代表的情况下完成任务?我以为我可以创建一个 Action 实例。

任何帮助或指示,非常感谢。

4

2 回答 2

7

该行:

Action<CalendarEventBase> emailCancelation = _trainingService.EmailTrainingCancellation;

实际上是期望协变,而不是逆变。但这在逻辑上没有意义。该方法需要 aTrainingEvent作为输入 - 如何将更通用的类型 ( CalendarEventBase) 传递给它?

这是不合法的:

// What if the method wants to make the lion roar but you pass in a goat?
Action<Mammal> mammalAction = MethodThatTakesALion; 

但这很好:

// Anything that you want to with an animal, you can do with a mammal.
Action<Mammal> mammalAction = MethodThatTakesAnAnimal; 
于 2011-02-11T11:42:40.597 回答
1

lambda 无法支持这一点,因为您声明的 emailCancelation 变量将接受 CalendarEventBase,但实际实现只会接受 TrainingEvent。如果有人使用 AuditEvent 参数调用 emailCancelation 会发生什么?

于 2011-02-11T11:45:06.383 回答