获取两个属性值列表的替代方法有哪些

时间:2013-05-14 22:51:25

标签: c# linq

获得相同结果的替代方法有哪些:

myCollection.Select(item => item.FirstValue)
  .Concat(myCollection.Select(item => item.SecondValue)).ToList();

该场景是一个名为Collection<MyClass>的{​​{1}},包含MyClass的实例(见下文)。我想为myCollection中的每个项目创建一个List<int>个实例,其中包含MyClass.FirstValueMyClass.SecondValue

myCollection

2 个答案:

答案 0 :(得分:2)

你可以尝试这样的事情,一个linqy单程解决方案:

private IEnumerable<int> Flatten(MyClass instance )
{
  yield return instance.Value1 ;
  yield return instance.Value2 ;
}

...

List<int> ints = myClasses.SelectMany( x => Flatten(x) ).ToList() ;

Flatten函数必须是一个真正的方法,因为你不能在闭包中使用yield return,以免你得到这个错误

  

错误CS1621:不能在匿名方法或lambda表达式

中使用yield语句

我怀疑Linq解决方案是否比明显的解决方案更好,更简单,更有效,更易于理解或其他任何方式:

List<int> ints = new List<int>() ;
foreach( MyClass item in myClasses )
{
  ints.Add(item.Value1) ;
  ints.Add(item.Value2) ;
}

我非常怀疑Linq解决方案会更快。如果您的MyClass对象集合可以廉价地报告其大小(例如,没有遍历集合),您可以通过将列表预分配到所需大小来优化上述内容:

List<int> ints = new List<int>( 2 * myClasses.Count ) ;
foreach( MyClass item in myClasses )
{
  ints.Add(item.Value1) ;
  ints.Add(item.Value2) ;
}

每次必须调整列表的后备存储大小时,这将节省重新分配和复制所需的时间。

答案 1 :(得分:1)

关于你最后的评论,他们是ID,我实际上是从一个不同的角度来处理这个问题。

如果您提前知道在类定义中有两个ID,请输入一个只返回一个数组或类型的IEnumerable的属性。

使用您的示例:

public class MyClass
{
    public int FirstValue { get; set; }
    public int SecondValue {get; set; }

    public int[] IDs
    {
        return new[] { FirstValue, SecondValue };
    }
}

然后收集ID的

List<int> allTheIds = new List<int>();
foreach (var mc in MyClassList)
{
    allTheIds.AddRange(mc.IDs);
}

这可能不是完美的语法,但我现在不在PC上进行测试!

然而,在我看来,这是最明智的方法,根据我的经验,我不认为使用Linq作为linqs缘故是一个好主意。

当然,这只是个人观点!