C#中的LINQ`名单,LT;接口与GT; .AddRange`方法不工作 [英] c# Linq `List<Interface>.AddRange` Method Not Working

查看:421
本文介绍了C#中的LINQ`名单,LT;接口与GT; .AddRange`方法不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有定义如下界面:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆