c#泛型接口和继承

时间:2018-04-15 20:56:40

标签: c# inheritance interface

我所选择的标题不太准确,但我不知道我在寻找的术语,或者它是否可能。

我想到的是一系列消费者< - procucer< -product。 消费者可以“消费”生产者和生产者“生产”某种类型的产品。因此我写道:

public interface IProduct
{
    string ProductName { get;  }
}

public class Product : IProduct
{
    public string ProductName { get { return "name of product"; } }
}

public interface IProducer<T>
{
    T ProducerProperty { get; set; }

    void ProducerMethod();
}

public class Producer<T> : IProducer<T> where T : IProduct
{
    public Producer()
    {

    }
    public T ProducerProperty { get; set; }

    public void ProducerMethod()
    {

    }
}

public interface IConsumer<T>
{
    T ConsumerProperty { get; set; }
    void ConsumerMethod();
}

public class Consumer<T> : IConsumer<T>
{
    private U producer;           //U should be IProducer<IProduct>, doesen't work

    public Consumer(U producer)   //U should be IProducer<IProduct>, doesen't work 
    {
        this.producer = producer;
    }

    public T ConsumerProperty { get; set; }

    public void ConsumerMethod()
    {

    }
}

和用例:

private IProducer<IProduct> producer;   //DeviceManager

private IConsumer<IProducer<IProduct>> consumer;  //DeviceViewManager            


public MainPage()
{
    this.InitializeComponent();

    producer = new Producer<IProduct>();
    consumer = new Consumer<IProducer<IProduct>>();
}

消费者类使用通用的“U”,此时这是虚构的。我希望消费者类使用类型U.在给定示例的上下文中,您可以想到一个用户从不同的面条制作中消费不同类型的面条。  我希望泛型类绑定到接口而不是实际的类。但我没有成功实现这一目标。我尝试用基类替换接口(例如:ProducerBase),但是需要实际的基类。

1 个答案:

答案 0 :(得分:0)

问题

如果您像这样定义Consumer

public class Consumer<T, U> : IConsumer<T, U>
{
    ...
}

你得到错误

  

CS0314类型&#39; T&#39;不能用作类型参数&#39; T&#39;在通用类型或方法IConsumer<T, U>&#39;中。没有拳击转换或类型参数转换来自&#39; T&#39;到了&nbsp;&#39; IProducer&#39;。

  

CS0314类型&#39; U&#39;不能用作类型参数&#39; U&#39;在通用类型或方法IConsumer<T, U>&#39;中。来自&#39; U&#39;没有拳击转换或类型参数转换。到了&nbsp;&#39; IProducer&#39;。

这告诉您的是,您无法从IConsumer<T, U>接口派生,因为它的泛型类型参数具有约束

public interface IConsumer<T, U>
    where T : IProducer<U>   // T needs to "be" an IProducer<U>
    where U : IProduct       // U needs to "be" an IProduct
{
    ...
}

因为界面需要 TU分别来自IProducer<U>IProduct编译器不会知道 T的泛型类型参数UConsumer实际上可以转换为IProducer<U>和{分别为{1}}。

解决方案

因此,如果您像这样定义IProduct并为ConsumerT添加约束

U

它会起作用,因为现在您指定public class Consumer<T, U> : IConsumer<T, U> where T : IProducer<U> where U : IProduct { ... } T将始终 分别为UIProducer<U>

我希望上面的解释是可以理解的;无论哪种方式,您还应该阅读this以便更好地理解泛型类型的约束。