I'm writing a networked application where objects are requested by id and are returned via a delegate callback:
public static void requestById<ModelType>(T id, Action<ModelType> callback)
where ModelType : AbstractModel<T>
{
}
For convenience I have a method for requesting multiple objects at a time:
public static void requestByIds<ModelType>
(List<T> ids, Action<List<ModelType>> callback)
where ModelType : AbstractModel<T>, new()
{
}
Further down the line I have an abstract model object that has multiple children, and a method for requesting it's children:
public abstract void requestSections(Action<List<AbstractSection>> callback);
And then an implementation in a concrete class:
public override void requestSections(Action<List<AbstractSection>> callback)
{
Section.requestByIds<Section>(this.sectionIds, callback);
}
Suddenly I find the delegate
Action<List<AbstractSection>>
is incompatible with
Action<List<Section>>
Is this a limitation of contravariance in C#? Is there any kind of workaround so I can get my override method to work? Thanks
List
is invariant, it is not covariant or contravariant.If you use an
IEnumerable<T>
rather than a list, than you can rely onIEnumerable<T>
being covariant with repsect toT
, which makesAction<IEnumerable<T>>
contravariant with respect toT
.