简体   繁体   English

C#泛型类型继承

[英]C# Generic Type Inheritance

I have an interface, ICheese, that I would like to be able to extend as I need. 我有一个接口ICheese,我希望能够根据需要进行扩展。 It is contained by class that is implementing the IFruit interface: 它包含在实现IFruit接口的类中:

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; 这样做是为了躲避C#没有返回类型协方差的事实。 I want to be able to have any implementation of IFruit and know that it has some version of ICheese inside of it. 我希望能够实现IFruit的任何实现,并且知道它内部具有某些版本的ICheese。

IFruit talks to a number of ICrackers, who have a reference to IFruit: IFruit与许多涉及IFruit的ICracker进行了交谈:

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: 只要ICracker的实现明确定义了它将使用哪种ICheese,它就可以工作:

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. 在那种情况下,在Saltine实例上调用Initialize(new Apple())是可行的。

However, if we have an ICracker like this: 但是,如果我们有这样的ICracker:

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

I cannot pass an Apple into Rizt's Initialize() function, even though Cheddar inherits from ICheese. 即使Cheddar继承自ICheese,也无法将Apple传递到Rizt的Initialize()函数中。 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. 基本想法是,我希望ICrackers能够说“我至少需要此版本的ICheese”,并能够接受至少提供该版本Icheese的任何IFruit。

You can make IFruit covariant in T : 您可以在T中使IFruit协变:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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