I'm not sure if my question is clear so I will make it clear by the code:
Basically I have a loader interface, with a generic type being an interface. Here, both Cat and Dog implements IAnimal.
private readonly IAnimalLoader<Cat> _catLoader;
private readonly IAnimalLoader<Dog> _dogLoader;
private IAnimalLoader<IAnimal> animalLoader;
public AnimalService(IAnimalLoader<Cat> catLoader,
IAnimalLoader<Dog> dogLoader)
{
_catLoader = catLoader;
_dogLoader = dogLoader;
}
Problem is when trying to assign either of the loader to animalLoader:
if (animal == AnimalType.Cat)
{
animalLoader = _catLoader;
}
else
{
animalLoader = _dogLoader;
}
C# complains about no implicit conversion from Cat
to IAnimal
, even though it implements it. No cast seems to fix the issue.
Any idea of what I'm doing wrong?
EDIT: Here is IAnimalLoader for clarification
public interface IAnimalLoader<T> where T : IAnimal
{
IQueryable<T> GetAllQueryable();
Task<T> GetAsync(string id);
}
While Cat
implements IAnimal
, IAnimalLoader<Cat>
has no such relationship with IAnimalLoader<IAnimal>
, which is what the error message is about.
Generally, one needs to mark the generic parameter as covariant for the conversion to succeed, the syntax is out T
IIRC, otherwise, check the C# language reference on generics' variance.
Updated (Thanks to the comment below): In your case, even that is not possible since one of the types, Task<T>
, is invariant. Only interfaces can be marked as variant, classes cannot be.