如何将一个集合转换为另一个集合

4

我有:

 IEnumerable<Foo> foolist

我希望你能将这个转换为:

IEnumerable<Bar> barlist

有没有一种LINQ / Lambda解决方案可以从一个对象移动到另一个对象?

这两个对象(foo和bar)都有简单的属性需要转换。例如:

 bar.MyYear = foo.Year

它们每个都有大约6个属性。

3个回答

13

你可以这样做:

IEnumerable<Bar> barlist = foolist.Select(
         foo => new Bar(foo.Year)); // Add other construction requirements here...

Enumerable.Select实际上是一个投影函数,因此它非常适合类型转换。根据帮助文档:

将序列的每个元素投射到新表单中。


编辑:

由于Bar没有构造函数(根据您的评论),因此您可以改用对象初始化器:

IEnumerable<Bar> barlist = foolist.Select(
     foo => new Bar() 
                {
                    Year = foo.Year, 
                    Month = foo.Month
                    // Add all other properties needed here...
                });

@Reed Copsey - 我不明白为什么你要将foo.Year传递给Bar()。bar没有构造函数,而是一堆属性。 - leora
@ooo:我编辑了我的答案,向您展示如何在不使用构造函数的情况下使其工作。 - Reed Copsey
好奇 - 为什么要踩这个回答 - 这似乎是一个完全合理的答案...? - Reed Copsey

1

就一般数据处理模式而言,我们正在寻找的是通用Map/Reduce范例的映射原则(如果您允许我打个双关语,这与LINQ中的Select相对应,正如@Reed Copsey所举的很好的例子)。

AutoMapper是一个库,它在适用LINQ的环境中实现了基于约定的投影/映射,并且如果您有足够复杂的需求来引入另一个库的认知负荷,那么它可能值得您去研究。


除了这里没有“reduce” - 它是纯粹的“map”。 - Reed Copsey
@Reed Copsey:是的,v1需要大量的工作。我曾经在苦苦寻找“投影”,但现在你已经有了,所以我不会抢走它! - Ruben Bartelink
@Reed Copsey:你现在感觉更有意义了吗?某些胆小的天才似乎并不这样认为,想把它变成-1。我很想看到他们的反驳观点在这里以光荣的帖子形式呈现:D - Ruben Bartelink
有时候我真的很想知道为什么我会在这个幼稚的网站上浪费时间。 - Ruben Bartelink
呵呵呵,我为你投了一票来抵消那个-1,尤其是现在它被重新表述了。 ;) - Reed Copsey
@Reed Copsey:谢谢!我很惊讶仍然有两个天才不同意(并且可能认为您的同情票是鼓励不良行为!),但不想解释他们的负投票或提供替代方案。我感到一种同侪压力徽章正在路上。尝试玩农场游戏可能是更好的利用我的时间。 - Ruben Bartelink

1
如果在Foo和Bar之间存在引用(或标识)转换,则这是泛型中协变或逆变的示例。
C#4.0支持泛型中的协变和逆变。
代码应该类似于:
IEnumerable foolist = new List(); IEnumerable barlist = foolist;
如果您的版本低于C#4.0,则Reed的答案适用于您。
更多信息请参见:

http://msdn.microsoft.com/library/dd799517(VS.100).aspx


+1个好点。从投票模式(以及对被接受回答的评论)来看,大家普遍认为他只是想要复制这些字段。 - Ruben Bartelink

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接