2013-05-23 4 views
0

Я пытаюсь определить IEnumerable свойства в объекте, а затем преобразовать его в словарь объектаСкомпилируйте Ошибка времени: SelectMany

Я написал запрос Linq с лямбда-выражения для преобразования списка списка в список, и я, следуя примеру из это msdn article

Когда я пытаюсь выполнить следующую программу в LINQPad я получаю время компиляции ошибку

void Main() 
{ 

     var list = new List<int>(); 
     list.Add(1); 
     list.Add(2); 

     var list2 = new List<string>(); 
     list2.Add("ab"); 
     list2.Add("xy"); 

     var obj = new { x = "hi", y = list, z = list2 , a =1}; 


     var properties = (obj.GetType()).GetProperties() 
                .Select(x => new {name =x.Name , value= x.GetValue(obj, null)}) 
                .Where(x=> x.value != null && (x.value is IEnumerable) && x.value.GetType() != typeof(string)) 
                .Select(x => new {name = x.name, value= x.value}); 


     Console.WriteLine(properties); 

     foreach(var item in properties) 
     { 
      var col = (IEnumerable) item.value; 
      foreach (var a in col) 
      { 
       Console.WriteLine("{0}-{1}",item.name,a); 
      } 
     } 




     //compile time error in following line 

     var abc = properties.SelectMany(prop => (IEnumerable)prop.value, (prop,propvalue) => new {prop,propvalue}) 
       .Select(propNameValue => 
        new { 
        name = propNameValue.prop.name, 
        value = propNameValue.propvalue 
        } 
       ); 

     Console.WriteLine(abc); 



} 

The type arguments for method 'System.Linq.Enumerable.SelectMany(System.Collections.Generic.IEnumerable, System.Func>, System.Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

Как я могу реструктурировать оператор SelectMany, чтобы избавиться от ошибки, чтобы я мог получить результат, похожий на вложенный цикл foreach?

ответ

1

Я хотел бы упростить задачу, предположим, у вас есть два списка: listInt и listString

var listInt = new List<int> { 1, 2 }; 
var listString = new List<string> { "ab", "xy" }; 

затем создать listObject, как показано ниже:

var listObject = new object[] { listInt, listString }; 

Если вы SelectMany:

var output = listObject.SelectMany(list => list); 

Вы получите ту же ошибку, что и ваш, поскольку два списка содержат разные типы. Можно было бы подумать, чтобы бросить в IEnumerable<object> как:

var output = listObject.SelectMany(list => (IEnumerable<object>)list); 

Но это не будет работать для listInt поскольку совместного варианта не поддерживает тип значения. Просто единственное решение, я бы:

var output = listObject.SelectMany(list => ((IEnumerable)list).Cast<object>()); 

Таким образом, на карту с вашей проблемой, вы можете изменить:

prop => ((IEnumerable)prop.value).Cast<object>(); 
+0

@Coung Le Спасибо за объяснение и сделать его проще для меня понять. – N30

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