2016-07-12 2 views
1

Следуя примеру на this post, я узнал, как динамически создавать список родовых типов. Теперь, моя проблема в том, что я хочу ADD элементов в созданный список из неизвестного исходного списка - есть ли способ достичь этого?C# Создавать общий список динамически во время выполнения

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

Моя без компиляции кода выглядит следующим образом:

IList<object> sourceList; // some list containing custom objects 
Type t = typeof(IList).MakeGenericType(sourceList[0].GetType()); 
IList res = (IList)Activator.CreateInstance(t); 
foreach (var item in sourceList) { 
    reportDS.Add(item); // obviously does not compile 
} 
+0

, что происходит, если вы накладываете деталь к тип списка – Armand

+2

Что такое 'sourceList' и' reportDS'? Вы знаете, какой тип _it_ находится во время компиляции? Если нет, почему бы вам просто не использовать «Список »? –

+1

Вы используете 'typeof (IList)', когда вам действительно нужно сказать 'typeof (List <>)' – Sean

ответ

1

Я рекомендовал бы переместить свой код в общий класс или функцию, перемещая отражения на более высокий уровень:

private static List<T> CloneListAs<T>(IList<object> source) 
{ 
    // Here we can do anything we want with T 
    // T == source[0].GetType() 
    return source.Cast<T>().ToList(); 
} 

назвать его:

IList<object> sourceList; // some list containing custom objects 
// sourceList = ... 

MethodInfo method = typeof(this).GetMethod("CloneListAs"); 
MethodInfo genericMethod = method.MakeGenericMethod(sourceList[0].GetType()); 

var reportDS = genericMethod.Invoke(null, new[] {sourceList}); 
+0

Удивительный! Это прекрасно работает, спасибо! – neggenbe

3

Там несколько причин, этот код не работает.

Во-первых, вам нужно создать экземпляр конкретного типа. Вы принимаете не общий интерфейс (IList) и пытаетесь создать из него общий тип. Вам нужно typeof(List<>).

Во-вторых, вы звоните AddItem, который не является методом на IList. Вам нужно позвонить Add, поэтому код не компилируется.

Этот код будет делать то, что вы хотите:

IList<object> sourceList; // some list containing custom objects 
Type t = typeof(List<>).MakeGenericType(sourceList[0].GetType()); 
IList res = (IList)Activator.CreateInstance(t); 

foreach(var item in sourceList) 
{ 
    res.Add(item); 
} 

Однако предположение, что sourceList[0] имеет правильный тип может прийти, чтобы укусить вас. Если этот список содержит последовательность объектов, не совместимых с первым элементом в списке, то любая попытка добавить к res не удастся. Как уже упоминалось в комментарии, вам лучше создать List<object> для хранения элементов.

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