Taylor Hadden
Taylor Hadden

Reputation: 21

C# Generic Type Inheritance

I have an interface, ICheese, that I would like to be able to extend as I need. It is contained by class that is implementing the IFruit interface:

public interface IFruit<T> where T : ICheese
{
    T : cheese { get; }
}

This was done to dodge the fact that C# doesn't have return type covariance; I want to be able to have any implementation of IFruit and know that it has some version of ICheese inside of it.

IFruit talks to a number of ICrackers, who have a reference to IFruit:

public interface ICracker<T> where T : ICheese
{
    void Initialize(IFruit<T> fruit);
}

public abstract class Cracker<T> where T : ICheese
{
    IFruit<T> fruit        

    public void Initialize(IFruit<T> fruit)
    {
        this.fruit = fruit;
    }
}

This works so long as the implementation of ICracker specifically defines which kind of ICheese it is going to use:

public class Apple : IFruit<Cheddar> {/* Implementation of Class */}

public class Saltine : Cracker<Cheddar> {/* Implementation of Class */}

In that instance, calling Initialize(new Apple()) on an instance of Saltine works.

However, if we have an ICracker like this:

public class Ritz : Cracker<ICheese> { /* Implementation of Class */ }

I cannot pass an Apple into Rizt's Initialize() function, even though Cheddar inherits from ICheese. Is there a way where I can get this to work or a pattern that would accomplish the same goals? The basic idea is that I want ICrackers to be able to say "I need at least this version of ICheese" and be able to accept any kind of IFruit that provides at least that version of ICheese.

Upvotes: 0

Views: 122

Answers (1)

Lee
Lee

Reputation: 144136

You can make IFruit covariant in T:

public interface IFruit<out T> where T : ICheese
{
    T Cheese { get; }
}

Upvotes: 1

Related Questions