问题描述
我发现,具体的对象的列表不能被添加到界面对象的列表。
I discovered that a list of concrete objects cannot be added to a list of interface object.
public static void AddJob(List<IJob> masterJobs, List<Job> jobs)
{
masterJobs.AddRange(jobs); //fail to compile
}
相反,需要使用下面的代码:
Instead, one needs to use the following code:
public static void AddJob(List<IJob> masterJobs, List<Job> jobs)
{
masterJobs.AddRange(jobs.Cast<IJob>());
}
什么是理性的背后?
What is the rational behind this?
推荐答案
拉塞是正确的,为什么这不会工作在C#3 - 没有从转换清单< IJob>
到列表<工作方式>
Lasse is right about why this won't work in C# 3 - there is no conversion from List<IJob>
to List<Job>
.
在C#4它将工作中,而不是列表中,因为的是协变,但因为的IEnumerable< T>
是协变的。因此,换句话说,代码将有效地为:
In C# 4 it will work, not because of the list being covariant, but because IEnumerable<T>
is covariant. So in other words, the code would effectively be:
public static void AddJob(List<IJob> masterJobs, List<Job> jobs)
{
IEnumerable<IJob> jobsTmp = jobs; // This is the covariance working
masterJobs.AddRange(jobs); // This is now fine
}
工作
工具的IEnumerable<工作>
,所以有一个引用转换为的IEnumerable< IJob>通过协方差
,所以这一切工作正常。要将呼叫演员LT; T>
有效地做类似的工作在C#3的解决方法 - 你用它来转换为的IEnumerable< IJob> ;
jobs
implements IEnumerable<Job>
, so there's a reference conversion to IEnumerable<IJob>
through covariance, so it all works fine. The call to Cast<T>
is effectively doing a similar job in your C# 3 workaround - you're using it to convert to an IEnumerable<IJob>
.
如果您想进一步了解通用的差异,有一个的的可用的视频,或阅读埃里克利珀的的的。
If you want to more about generic variance, there's a video of my NDC 2010 talk available, or read Eric Lippert's series of blog posts on it.
这篇关于清单< IJob> .AddRange(列表<人才与GT;)不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!