将继承的泛型添加到通用列表

时间:2016-03-17 09:50:37

标签: c# list generics inheritance

我正在尝试将对象添加到列表中,其中对象是继承接口的泛型。

听众的基类:

public class Listener<T> : IListener<T>
    where T : ICaller {

    public Listener()  {

    }

    public Type GetCallerType() {
        return typeof(T);
    }

    public virtual void Received(Connection connection, T obj) {}
}

示例监听器:

public class ClientPacketListener<T> : Listener<T>
    where T : Packet {
}

我想将它们添加到此列表中:

Listener<ICaller> listeners = new Listener<ICaller>();

在这种情况下,Packet继承了ICaller,因此所有内容都应该可以转换为基类型。错误是它无法投射。 我已经查看了其他一些问题,但它们只适用于<T>的泛型,而不是监听器类。有没有办法让这个工作与否?

2 个答案:

答案 0 :(得分:0)

只需改变

 public interface IListener<out T>
 {

 }

public class ClientPacketListener : Listener<Packet>    
{
   //............ your code
}
那么你可以这样写下来。

 IListener<ICaller> listeners = new ClientPacketListener();

但不低于一个

 //Listener<ICaller> listeners = new ClientPacketListener();

编辑:整个故事是协方差反方差

https://msdn.microsoft.com/en-us/library/ee207183.aspx

这是关于

的简短说明
  

&#34; out T&#34;意味着类型T是&#34;协变&#34;。这限制了T出现   仅作为泛型类方法中的返回(出站)值,   界面或方法。这意味着你可以施展   类型/接口/方法到具有超类型T的等价物。   ICovariant可以转发给ICovariant。

答案 1 :(得分:0)

如果您要将IListener<T>声明更改为IListener<out T> T 协变,我认为您可以解决问题。

它应该允许你这样做

IListener<ICaller> listener = new ClientPacketListener<Packet>();

有关详细信息,请参阅MSDN out (Generic Modifier)