dunnry
dunnry

Reputation: 6868

Type conversion with Generics

Suppose I have a concrete class - 'Giraffe' that implements 'IMammal'. In my scenario, I can create a generic repository and factory like so:

public MammalFactory : IMammalFactory
{
    public IMammalRepository<T> GetMammalRepo<T>() where T: IMammal, new()
    {
        return new MammalRepository<T>();
    }
}

MammalRepository can now be of type Giraffe or Antelope as long as they both implement IMammal. So far, so good.

However, I can't use an expression like this (won't compile and cannot cast):

Func<IMammalRepository<IMammal>> = () => this.factory.GetMammalRepo<Giraffe>();

I have a method that is very similar between my classes and I want to factor them down to something like:

//called from different implementations
public void FeedAnimalInternal(Func<IMammalRepository<IMammal>> repo, Action<IMammal> doIt)
{
    var animalRepo = repo();
    var animals = animalRepo.GetAnimals(); //might be giraffe or might be something else
    foreach (var animal in animals) { doIt(animal); }
}

First, why won't the Func<> (first one) compile? Is this a covariance thing? Next, any idea how I can accomplish something similar to what I am trying to do?

Upvotes: 0

Views: 92

Answers (2)

MisterXero
MisterXero

Reputation: 1128

Check out Eric Lippert's blog posts on Covariance and Contravariance. It is a ten part series I think.

Upvotes: 0

Jacob
Jacob

Reputation: 78850

Yes, it's a covariance thing. If you define IMammalRepository like this:

public interface IMammalRepository<out T> where T : IMammal
{
    // ...
}

This should solve your problem.

Upvotes: 3

Related Questions