funcs expressions delegate c# lambda delegates variance

expressions - Contravarianza en acción lambda-C#



lambda expressions c# (2)

Tengo una jerarquía de clases como esta

public abstract class CalendarEventBase{} public class TrainingEvent : CalendarEventBase{} public class AuditEvent : CalendarEventBase{}

Quería crear una acción Action lamda que tuviera un parámetro de tipo genérico de tipo CalendarEventBase que pudiera asignar a los siguientes métodos diferentes:

public void EmailCancelation(TrainingEvent trainingEvent) public void EmailCancelation(AuditEvent auditEvent)

Creé la siguiente asignación ilegal:

Action<CalendarEventBase> emailCancelation = _trainingService.EmailTrainingCancellation;

El compilador se queja de que esperaba un método con void (CalendarEventBase) como firma. Me sorprendió esto porque pensé que aceptaría un tipo más derivado.

Para evitar esto, creé el siguiente delegado que me permite completar mi tarea:

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

Mi pregunta es, ¿podría haber completado la tarea sin tener que crear un delegado adicional? Pensé que podría crear una instancia de Acción.

Cualquier ayuda o consejos, muy apreciados.


El lambda no puede soportar esto, porque la variable emailCancelation que ha declarado aceptará un CalendarEventBase, pero la implementación real solo aceptará el TrainingEvent. ¿Qué pasaría si alguien llamara a EmailCancelation con un parámetro AuditEvent?


La línea:

Action<CalendarEventBase> emailCancelation = _trainingService.EmailTrainingCancellation;

en realidad está esperando la covarianza , no la contradicción . Pero eso lógicamente no tiene sentido; el método espera un TrainingEvent como entrada, ¿cómo se puede pasar un tipo más general ( CalendarEventBase ) a él?

Esto no es legal

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

pero esto está bien:

// Anything that you want to with an animal, you can do with a mammal. Action<Mammal> mammalAction = MethodThatTakesAnAnimal;