C#中的LINQ`名单,LT;接口与GT; .AddRange`方法不工作 [英] c# Linq `List<Interface>.AddRange` Method Not Working
问题描述
我有定义如下界面:
public interface TestInterface{
int id { get; set; }
}
和两个实现该接口的LINQ到SQL类:
And two Linq-to-SQL classes implementing that interface:
public class tblTestA : TestInterface{
public int id { get; set; }
}
public class tblTestB : TestInterface{
public int id { get; set; }
}
我有IEnumerable的列表a和b从tblTestA由数据库的记录填充和tblTestB
I have IEnumerable lists a and b populated by the database records from tblTestA and tblTestB
IEnumerable<tblTestA> a = db.tblTestAs.AsEnumerable();
IEnumerable<tblTestB> b = db.tblTestBs.AsEnumerable();
但是,下面是不允许
However, the following is not permitted:
List<TestInterface> list = new List<TestInterface>();
list.AddRange(a);
list.AddRange(b);
我必须做如下:
I have to do as follows:
foreach(tblTestA item in a)
list.Add(item)
foreach(tblTestB item in b)
list.Add(item)
有什么我做错了吗?感谢您的帮助。
Is there something I am doing wrong? Thanks for any help
推荐答案
这个工作在C#4,由于的通用协的。不像C#的早期版本中,有一个从的IEnumerable℃的转换; tblTestA>
到的IEnumerable< TestInterface方式>
This works in C# 4, due to generic covariance. Unlike previous versions of C#, there is a conversion from IEnumerable<tblTestA>
to IEnumerable<TestInterface>
.
该功能已经在从V2的CLR,但它只是在C#4被曝光(和框架类型并没有充分利用它的.NET 4前两种)。它的只有的适用于通用的接口和委托(而不是类)和仅供参考类型(所以没有从转换IEnumerable的< INT>
到<$ 。C $ C>的IEnumerable<对象> 为例)也只能在有意义 - 的IEnumerable< T>
是协变的对象只来API的走出去,而的IList< T>
是不变的,因为你可以与API也添加值
The functionality has been in the CLR from v2, but it's only been exposed in C# 4 (and the framework types didn't take advantage of it before .NET 4 either). It only applies to generic interfaces and delegates (not classes) and only for reference types (so there's no conversion from IEnumerable<int>
to IEnumerable<object>
for example.) It also only works where it makes sense - IEnumerable<T>
is covariant as objects only come "out" of the API, whereas IList<T>
is invariant because you can add values with that API too.
通用逆变也支持,在其他方向上的工作 - 这样,例如,你可以从的IComparer<转换;对象>
到的IComparer<字符串方式>
Generic contravariance is also supported, working in the other direction - so for example you can convert from IComparer<object>
to IComparer<string>
.
如果你不使用C#4,然后用添的建议 Enumerable.Cast< T>
是一个很好的 - 你失去一点点效率,但是它会奏效
If you're not using C# 4, then Tim's suggestion of using Enumerable.Cast<T>
is a good one - you lose a little efficiency, but it will work.
如果您想了解更多有关通用方差,埃里克利珀有一长串它的博客文章,我给2010 NDC一说起它,你可以在 NDC视频页面。
If you want to learn more about generic variance, Eric Lippert has a long series of blog posts about it, and I gave a talk about it at NDC 2010 which you can watch on the NDC video page.
这篇关于C#中的LINQ`名单,LT;接口与GT; .AddRange`方法不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!