0

有哪些替代方法可以实现由此产生的相同结果:

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

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

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

2 回答 2

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:yield 语句不能在匿名方法或 lambda 表达式中使用

我怀疑 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) ;
}

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

于 2013-05-14T23:10:31.817 回答
1

关于你最后的评论,他们是 ID,我实际上是从一个不同的方面来解决这个问题的。

如果您提前知道您的 Class 定义中有两个 ID,请放入一个仅返回 Array 或 Type 的 IEnumerable 的属性。

使用您的示例:

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

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

然后收集身份证

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

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

但是,在我看来,这是最明智的方法,根据我的经验,我认为将 Linq 用于 linqs 并不是一个好主意。

当然这只是个人意见!

于 2013-05-14T23:08:10.590 回答