我有一个包含两个整数的类,例如A
和B
:
public class MyClass {
public int A { get; set; }
public int B { get; set; }
...other stuff...
}
我在代码中有一个MyCollection
类型ObservableCollection<MyClass>
,并且需要获得所有值的IEnumerable<int>
- A
&#39; s和B
- 一起列在一个列表中。
我已经弄清楚如何使用相当冗长的代码(为了示例目的而将其简化为仅低于一级,但实际上是&#34;来自&#34;调用和从嵌套列表中选择值的3个级别) :
IEnumerable<int> intsA=
(from x in MyCollection
select x.A);
IEnumerable<int> intsB =
(from x in MyCollection
select x.B);
IEnumerable<int> allInts = intsA.Concat(intsB);
似乎应该有一种方法可以同时将两个变量选择到同一IEnumerable<int>
。显然下面不起作用,但我喜欢像
IEnumerable<int> allInts = (from x in MyCollection select x.A, x.B);
这样的事情是否存在比我上面的更优雅?
我找到了如何在匿名类型here中选择多个值,但这并没有使它成为相同的IEnumerable,并且仍然需要更多代码/处理来获取项目。
(顺便说一句,使用.NET 4.5.1,如果这有所不同。)谢谢!
答案 0 :(得分:13)
您可以使用SelectMany
:
var result = source.SelectMany(x => new[] { x.A, x.B });
但是因为你为每个对象分配了一个新的数组,我不知道它的性能如何(或者你可能不那么关心它)。
您可以在类型上声明GetIntValues
,返回IEnumerable<int>
:
public class MyClass {
public int A { get; set; }
public int B { get; set; }
...other stuff...
public IEnumerable<int> GetIntValues()
{
yield return A;
yield return B;
}
}
并像这样使用它:
var result = source.SelectMany(x => x.GetIntValues());
但是每个元素还有一个额外的分配。
答案 1 :(得分:6)
确实很容易:
IEnumerable<int> allInts = MyCollection.Select(i => i.A)
.Concat(MyCollection.Select(i => i.B));
它与你所写的相同,但不那么冗长。它使用lambda语法而不是查询理解语法。
如果您想避免额外分配,请使用它。如果您不关心GC压力,Marcin的解决方案甚至更短。此外,它以与其解决方案不同的顺序输出元素。