【问题标题】:Adding inherited generics to a generic list将继承的泛型添加到泛型列表
【发布时间】:2016-07-03 14:06:21
【问题描述】:

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

监听器基类:

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,因此所有内容都应该能够转换为基本类型。错误是它不能被强制转换。 我查看了其他一些问题,但它们仅适用于 &lt;T&gt; 的泛型,而不适用于侦听器类。有没有办法让它工作?

【问题讨论】:

  • Listener&lt;T&gt;ClientPacketListener&lt;T&gt; 都没有实现 ICaller。请说明你想在这里做什么以及你希望它如何表现。
  • T 实现 ICaller(在这种情况下为数据包)。我想创建一个可以循环的通用列表,但是除了给定的 T 类型之外,类类型应该是通用的。
  • 你是说Listener&lt;ICaller&gt; listener = new ClientPacketListener&lt;Packet&gt;();
  • 你能改一下IListener&lt;T&gt;代码吗?
  • 嗯,这就是我想要做的,但不知何故不起作用,我不知道为什么。

标签: c# list generics inheritance


【解决方案1】:

这里改一下

 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

这里有一个简短的说明

“out T”表示类型 T 是“协变的”。这限制了 T 出现 仅作为泛型类方法中的返回(出站)值, 接口或方法。这意味着您可以将 类型/接口/方法与具有 T 的超类型的等价物。 ICovariant 可以强制转换为 ICovariant。

【讨论】:

  • 啊,我不知道!我仍然有一个问题,我想让 Packet 作为 ICaller 泛型,否则我无法监听任何类型的对象。它只是说它不能将 Packet 转换为 ICaller,即使 Packet 实现了 ICaller..
  • 你想要像Listener&lt;ICaller&gt; listeners = new ClientPacketListener();这样的线路
  • 没错,但是即使Packet正在实现ICaller,它也无法将Packet转换为ICaller。
【解决方案2】:

如果您将IListener&lt;T&gt; 声明更改为IListener&lt;out T&gt; 使T 协变,我认为您可以解决问题。

它应该允许你这样做

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

更多信息请阅读MSDN out (Generic Modifier)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 2018-09-27
    • 2015-09-15
    • 1970-01-01
    相关资源
    最近更新 更多