Action lambda 中的逆变 - C#
我有一个像这样的类层次结构,
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 实例。
任何帮助或指示,非常感谢。
I have a class hierarchy like this
public abstract class CalendarEventBase{}
public class TrainingEvent : CalendarEventBase{}
public class AuditEvent : CalendarEventBase{}
I wanted to create an action Action lamda that had a generic type paramater of type CalendarEventBase that I could assign to the following different methods:
public void EmailCancelation(TrainingEvent trainingEvent)
public void EmailCancelation(AuditEvent auditEvent)
I created the following illegal assignment:
Action<CalendarEventBase> emailCancelation = _trainingService.EmailTrainingCancellation;
The compiler complains that it was expecting a method with void(CalendarEventBase) as a signature. I was surprised by this as I thought it would accept a more derived type.
To get round this, I created the following delegate that allows me to complete my task:
public delegate void EmailCancelation<in T>(T calendarEvent) where T : CalendarEventBase;
My question is, could I have completed the task without having to create an additional delegate? I thought I could just create an Action instance.
Any help or pointers, greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
该行:
实际上期望的是协方差,而不是逆变。但这在逻辑上是没有意义的;该方法需要
TrainingEvent
作为输入 - 如何将更通用类型 (CalendarEventBase
) 传递给它?这是不合法的:
但这很好:
The line:
is actually expecting covariance, not contravariance. But that logically doesn't make sense; the method expects a
TrainingEvent
as input - how can you pass a more general type (CalendarEventBase
) to it?This isn't legal:
but this is fine:
lambda 无法支持这一点,因为您声明的 emailCancelation 变量将接受 CalendarEventBase,但实际实现将仅接受 TrainingEvent。如果有人使用 AuditEvent 参数调用 emailCancelation 会发生什么?
The lambda can't support this, because the emailCancelation variable you've declared will accept a CalendarEventBase, but the actual implementation will only accept the TrainingEvent. What would happen if someone were to call emailCancelation with an AuditEvent parameter?