简体   繁体   中英

Assign generic type class implementing interface to generic type being interface

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM