行动中的逆变性lambda - C#

dag*_*da1 5 c# lambda delegates variance

我有这样的类层次结构

public abstract class CalendarEventBase{}

public class TrainingEvent : CalendarEventBase{}

public class AuditEvent : CalendarEventBase{}
Run Code Online (Sandbox Code Playgroud)

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

public void EmailCancelation(TrainingEvent trainingEvent)

public void EmailCancelation(AuditEvent auditEvent)
Run Code Online (Sandbox Code Playgroud)

我创建了以下非法作业:

Action<CalendarEventBase> emailCancelation = _trainingService.EmailTrainingCancellation;
Run Code Online (Sandbox Code Playgroud)

编译器抱怨它期望一个带有void(CalendarEventBase)的方法作为签名.我对此感到惊讶,因为我认为它会接受更多衍生类型.

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

public delegate void EmailCancelation<in T>(T calendarEvent) where T : CalendarEventBase;
Run Code Online (Sandbox Code Playgroud)

我的问题是,我是否可以完成任务而无需创建额外的代表?我以为我可以创建一个Action实例.

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

Ani*_*Ani 7

这条线:

Action<CalendarEventBase> emailCancelation = _trainingService.EmailTrainingCancellation;
Run Code Online (Sandbox Code Playgroud)

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

这不合法:

// What if the method wants to make the lion roar but you pass in a goat?
Action<Mammal> mammalAction = MethodThatTakesALion; 
Run Code Online (Sandbox Code Playgroud)

但这没关系:

// Anything that you want to with an animal, you can do with a mammal.
Action<Mammal> mammalAction = MethodThatTakesAnAnimal; 
Run Code Online (Sandbox Code Playgroud)