Можно ли заменить этот цикл foreach на Linq? - PullRequest
3 голосов
/ 16 марта 2011

У меня есть цикл 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 ]

5 голосов
/ 16 марта 2011

Вы можете сделать:

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 голос
/ 16 марта 2011

Примерно так должно работать:

list1 = device.MemoryBanks
              .Select( x=> x.MemoryBlocks.AsEnumerable<IMemory>().Concat(x))
              .SelectMany( x=>x)
              .ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...