Question

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

Was it helpful?

Solution

List is invariant, it is not covariant or contravariant.

If you use an IEnumerable<T> rather than a list, than you can rely on IEnumerable<T> being covariant with repsect to T, which makes Action<IEnumerable<T>> contravariant with respect to T.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top