Преобразовать словарьперечислить <foo>в C # 2.0 - PullRequest
4 голосов
/ 28 октября 2010

Есть ли другой способ получить List<foo> напрямую из ValueCollection.

Текущий код, который я использую ниже

 Dictionary<string,List<foo>> dic;

 List<foo> list= new List<foo>();

 foreach (List<foo> var in dic.Values)
 {               
      list.AddRange(var);
 }  

ИЛИ

List<List<foo>> list= new List<List<foo>>(dic.Values);

Выше преобразованиядает мне List<List<foo>, но я хочу List<foo> из dic.values ​​без использования для каждого цикла, если возможно, используя .NET 2.0.

Ответы [ 5 ]

2 голосов
/ 28 октября 2010

Без использования LINQ или .NET 3.5 я не знаю ни одного способа сделать это без какого-либо цикла for.Даже с LINQ, где-то в рамках foreach будет делать то же самое.

Если вы прикованы к .NET 2.0, но имеете доступ к более поздней версии компилятора C #, вы можете использовать LinqBridge.dllчтобы добиться того же эффекта - читайте об этом здесь .Обратите внимание, что для этого потребуется как минимум VS 2008 (нацеливание на платформу 2.0).Если вы можете использовать это, то все, что вам нужно сделать, это

using System.Linq;

...

dic.Values.SelectMany(v => v).ToList();
1 голос
/ 28 октября 2010

Ваш цикл foreach должен быть

Dictionary<string,List<foo>> dic;

 List<foo> list= new List<foo>();

 foreach (List<foo> var in dic.Values)
 {    
      foreach(foo bar in var){           
          list.AddRange(bar);
      }
 }  

Вы добавляли каждый список в список, когда хотели добавить каждый элемент каждого списка в список.

И полностью пропустил для каждой части цикла в вашем вопросе.

Я не думаю, что это возможно в C # 2.0. В основе LINQ лежит итерация над IEnumerable, и все, что делает foreach

1 голос
/ 28 октября 2010

EDIT: простое решение LINQ (недоступно в .NET 2.0)

dic.Values.SelectMany(list => list).ToList()

Если вам не нужен список и все в порядке с IEnumerable, то отключите ToList ()

Более сложное решение:

  1. Определите класс, который реализует IList и имеет конструктор, который принимает ValueCollection или ICollection
  2. Реализуйте все методы на этом. Вы можете отслеживать весь список T и индекс текущего списка, над которым вы работаете.

использование

return new MyListCombiner<foo>(dict.Values);
0 голосов
/ 28 октября 2010

В C # 2.0 вы должны использовать либо цикл, либо LINQ для бедного человека с кодом, который выглядит следующим образом:

Linq(dic.Values).SelectMany(delegate(List<foo> list) { return list; }).ToList()

Где вы определяете Linq () как

static PoorMansLinq<T> Linq<T>(IEnumerable<T> source)
{
    return new PoorMansLinq<T>(source);
}

Я заметил, что первая строка в настоящее время не работает, и я отправил обновление, чтобы исправить это.В то же время вы можете использовать следующее в качестве обходного пути:

Linq(Linq(dic.Values).SelectMany(delegate(List<foo> list) { return list; })).ToList()

Вы также можете использовать LinqBridge и напрямую вызывать Enumerable, но без C # 3.0 это громоздко.

0 голосов
/ 28 октября 2010

В конечном счете, любой метод, который вы выберете, будет включать цикл for на некотором уровне абстракции. Если вы остаетесь в чистом .NET 2.0, вам придется написать цикл for где-то в вашем коде. Такая конгломерация данных является одной из основных целей LINQ. См. SelectMany метод:

http://msdn.microsoft.com/en-us/library/system.linq.enumerable.selectmany.aspx

В зависимости от ваших требований, вы можете подключиться к .NET 3.0 / 3.5, но все же скомпилировать в более старой версии набора инструментов. Вам все равно нужно иметь 3.0 / 3.5 на той коробке, на которой вы запускаете приложение, но вам не придется обновлять свои инструменты. Синтаксис также не будет выглядеть привлекательно, потому что вам придется обращаться к методам расширения через синтаксис статического метода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...