是否有可能用Linq替换这个foreach循环?

时间:2011-03-16 15:43:28

标签: c# linq foreach

我有一个foreach循环,我想用Linq查询替换,但我无法弄清楚如何编写查询。请参阅下面的示例和TIA。

using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication
{
    class ExampleProgram
    {
        static void Main( string[] args )
        {
            Device device = new Device();

            // The goal is to populate this list.
            var list1 = new List<IMemory>();

            // I would like to replace this loop with a Linq query
            foreach( MemoryBank memoryBank in device.MemoryBanks )
            {               
                list1.Add( memoryBank ); // add the memory bank

                foreach( MemoryBlock memoryBlock in memoryBank.MemoryBlocks )
                    list1.Add( memoryBlock ); // add the memory block
            }

            //var list2 = from memoryBank in device.MemoryBanks
            //            from memoryBlock in memoryBank.MemoryBlocks
            //            select ???;
        }
    }

    interface IMemory 
    {}

    public class Device
    { 
        public IList<MemoryBank> MemoryBanks { get; set; } 
    }

    public class MemoryBank : MemoryBlock, IMemory
    {
        public IList<MemoryBlock> MemoryBlocks { get; set; } 
    }

    public class MemoryBlock : IMemory 
    { }
}

2 个答案:

答案 0 :(得分:5)

你可以这样做:

var list1 = device.MemoryBanks
                  .SelectMany(m => new[] { m }.Concat(m.MemoryBlocks))
                  .ToList();

请注意,这会在您的示例中创建List<MemoryBlock>而不是List<IMemory>。要制作接口类型列表,请进行最后的呼叫ToList<IMemory>()

编辑:

在.NET 3.5中,IEnumerable<T>接口不是协变的,你可以这样做:

var list1 = device.MemoryBanks
                  .SelectMany(m => new IMemory[] { m }
                                       .Concat(m.MemoryBlocks.Cast<IMemory>()))
                  .ToList();

答案 1 :(得分:1)

这样的事情应该有效:

list1 = device.MemoryBanks
              .Select( x=> x.MemoryBlocks.AsEnumerable<IMemory>().Concat(x))
              .SelectMany( x=>x)
              .ToList();