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()代码>和asignl.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条评论很感兴趣,想知道那次对话的另一半是什么;但你只需要。