C# 如何将泛型类型的具体实现分配给泛型类型列表

C# 如何将泛型类型的具体实现分配给泛型类型列表,c#,C#,我一直在试图理解为什么下面的代码会产生编译错误,以及如何避免这个错误 public interface IA { } public class AImp : IA { } public interface IConsumer<T> where T : IA { void Consume(T val); } public class Consumer : IConsumer<AImp> { public void Consume(AImp val)

我一直在试图理解为什么下面的代码会产生编译错误,以及如何避免这个错误

public interface IA { }
public class AImp : IA { }

public interface IConsumer<T> where T : IA
{
    void Consume(T val);
}

public class Consumer : IConsumer<AImp>
{
    public void Consume(AImp val)
    {
        // do smth
    }
}

public class Program
{
    public static void Main()
    {
        IList<IConsumer<IA>> l1 = new List<IConsumer<IA>>();
        l1.Add(new Consumer());  // generate compile error cannot convert from consumer to IConsumer<IA>

    }
}
公共接口IA{}
公共类AImp:IA{}
公共接口i消费者,其中T:IA
{
无效消耗(T val);
}
公共类消费者:IConsumer
{
公共无效消费(AImp val)
{
//做smth
}
}
公共课程
{
公共静态void Main()
{
IList l1=新列表();
l1.Add(new Consumer());//生成编译错误无法从Consumer转换为IConsumer
}
}
如果我可以创建
IList l=new List()和asign
l.Add(新AImp()),我不明白为什么泛型类型不起作用。也许我遗漏了一些基本的东西


我也没有从谷歌找到任何有希望的潜在客户。

您会收到一条错误消息,因为消费者没有从IConsumer继承。它继承自IConsumer

使用这种模板类有一种特殊的技术,您必须创建一个IConsumer接口,它不是这样的泛型类型:

public interface IA { }
public class AImp : IA { }

public interface IConsumer
{
}

public interface IConsumer<T> : IConsumer
    where T : IA
{
    void Consume(T val);
}

public class Consumer : IConsumer<AImp>
{
    public void Consume(AImp val)
    {
        // do smth
    }
}

public class Program
{
    public static void Main()
    {
        IList<IConsumer> l1 = new List<IConsumer>();
        l1.Add(new Consumer());  // ok
    }
}
公共接口IA{}
公共类AImp:IA{}
公共接口IConsumer
{
}
公共接口IConsumer:IConsumer
T:IA在哪里
{
无效消耗(T val);
}
公共类消费者:IConsumer
{
公共无效消费(AImp val)
{
//做smth
}
}
公共课程
{
公共静态void Main()
{
IList l1=新列表();
l1.Add(新使用者());//确定
}
}

这基本上就是IEnumerable和ICollection泛型和非泛型版本背后的想法。

@一般来说,我相信协方差只适用于返回类型,而不适用于参数。您想要
公共类消费者:IConsumer
而不是
公共类消费者:IConsumer
,这很有趣,当您在
out
时,此处
接口IConsumer
,存在编译时错误,该错误与
IConsumer.Consume
方法的方差无效。根据MSDN,您不能使用协变类型参数作为接口方法的泛型类型约束。这是正常的,但这对您不太好,IMHO,您只能将
类消费者:IConsumer
更改为
类消费者:IConsumer
,这将解决差异编译时错误。因为
Consumer
不是
IConsumer
-如果是,您将能够定义一个类
class BImp:IA{}
,然后执行
IConsumer c=new Consumer();c、 消费(新BImp())。这是不安全的,因为
BImp
AImp
不兼容。换句话说,
消费者
不能消费任何
IA
,只能消费
IA
的一个特定子类型,即
AImp
。您是否建议解决方案是声明空接口
IConsumer
?如果是这样的话,也许值得一读微软的代码分析规则。此外,当你从
l1
中得到某样东西时,除非你将它转换成其他东西,否则你不能用它做任何事情。是的,P.S。我对上面的3条评论很感兴趣,想知道那次对话的另一半是什么;但你只需要。