2010-07-23 5 views
3

класса я хочу работать на обеспечивает добытчик типа IEnumerable<X> и IEnumerable<Y> где X & Y являются подклассами типа T. Я хочу, чтобы перебирать содержимое как лечащие их тип T. Есть ли удобный способ объединить оба в нечто, что можно увидеть как IEnumerable<T>?Как вы можете создать коллекцию на основе нескольких IEnumerables

Пример:

 IEnumerable<HeaderPart> headers = templateFile.MainDocumentPart.HeaderParts; 
     IEnumerable<FooterPart> footers = templateFile.MainDocumentPart.FooterParts; 
     List<OpenXmlPart> result = new List<OpenXmlPart>(); 
     result.Concat<OpenXmlPart>(footers); 

HeaderPart и FooterPart являются подклассами OpenXmlPart, но третья линия терпит неудачу:

'System.Collections.Generic.IEnumerable' не содержит определения для 'Concat' и лучший метод расширения перегрузка 'System.Linq.Enumerable.Concat (System.Collections.Generic.IEnumerable, System.Collections.Generic.IEnumerabl е)» имеет некоторые недопустимые аргументы

Обратите внимание, я не могу изменить либо из исходных данных, мне нужно, чтобы создать новую коллекцию - на самом деле я хочу сделать foreach над ним. .

ответ

6

Вы можете использовать функцию Cast для преобразования IEnumerable<X> в IEnumerable<T>, а затем Concat, чтобы добавить вторую серию

Нечто вроде:

listB.Cast<A>().Concat(listC.Cast<A>()) 
3

В C#/NET 4 или более поздней версии вы можете использовать Enumerable.Concat<T>:

IEnumerable<T> result = xs.Concat<T>(ys); 

Для вашего конкретного случая вы можете использовать List.AddRange:

List<OpenXmlPart> result = new List<OpenXmlPart>(); 
result.AddRange(headers.Cast<OpenXmlPart>()); 
result.AddRange(footers.Cast<OpenXmlPart>()); 
+0

Ни один из типов, которые я пытаюсь использовать, не имеет метода Concat ... Что вы имеете в виду? –

+0

Я получил свои комментарии, испорченные, измененные. –

+0

@John: В какой версии .NET вы используете? –

0

Если вы уверены, что ваш IEnumerable список вы можете использовать AddRange()

IEnumerable<int> list1 = new List<int>() { 1, 2, 3 }; 
IEnumerable<int> list2 = new List<int>() { 4, 5, 6 }; 
((List<int>)list1).AddRange(list2); 
+0

Не работает в моем коде. В нем говорится, что типы несовместимы, поскольку это не все одинаковые типы, но два списка, содержащие разные подтипы одной и той же базы. Также весь смысл интерфейсов - я понятия не имею о внутреннем типе из класса .Net. Два метода возвращают 'IEnumerable ' и 'IEnumerable ' это все, что я знаю. –

1

Не проверял, и не знают о функциональности готовой для него, но вместо того, чтобы выделять новые хранение и перемещение данных о, вы должны быть в состоянии реализовать свой собственный класс EnumeratorBinder<T, X, Y> шаблон, связывающий два IEnumerable экземпляра в конструкторе, и implement что-то на линии

IEnumerable<T> GetEnumerable() 
{ 
    foreach (X x in _enumX) 
    yield return x; 
    foreach (Y y in _enumY) 
    yield return y; 
} 

с подходящими ограничениями шаблона ...

+0

Да, это почти то, что делает метод LINK 'Concat'. http://msdn.microsoft.com/en-us/library/bb302894.aspx – LukeH

+0

Ah - не проверял реализацию: его перетасованный список подписи. О, ну, это весело изобретать колесо! –

Смежные вопросы