2014-01-14 6 views
1

Усиливая от добротности & Как дела со сквозными через свойство объекта (https://stackoverflow.com/questions/15586123/loop-through-object-and-get-properties, Loop Through An Objects Properties In C#), где у вас есть:Использования LINQ Переберите внутренние свойства класса в коллекции внешнего класса

  • коллекция объектов class1 (т.е. listObj1)
  • каждый Class1 содержит коллекцию объектов class2 (т.е. dictObj2)

Как бы вам:

  • эффективно определять свойства внутреннего класса (class2)
  • петли через свойство внутреннего класса (class2)
  • цикла через коллекцию объектов class1 (listObj1) выбирают все экземпляры в Class2 свойство
  • вывести коллекцию свойств Class2 (например, первая итерация вернет коллекцию MeasurementA, по одному от каждого объекта Class1).
  • и группа коллекция по Class1.PropertyA и Class1.PropertyB

Вы найдете ниже шероховатой карте классов, участвующих.

Я пытался использовать запрос LINQ без успеха. Любые идеи или рекомендации будут высоко оценены.

class MainClass { 
    List<Class1> listObj1 
} 

class Class1 { 
    // a number of fields including... 
    int PropertyA { get; set; } 
    int PropertyB { get; set; } 
    Dictionary<int, Class2> dictObj2 { get; set; } 
} 

class Class2 { 
    // a number of fields all of type double... 
    double MeasurementA { get; set; } 
    double MeasurementB { get; set; } 
    double MeasurementC { get; set; } 
} 
+0

«эффективно определять свойства внутреннего класса» - с помощью «интерфейса». – Gusdor

+0

Как выглядит ваш запрос LINQ? –

+1

Разве вы не знаете типы этих классов перед рукой? Если нет, то откуда вы знаете, что внешний класс будет иметь коллекцию внутреннего класса? Похоже, вы спрашиваете, как использовать Reflection, но если вы знаете типы раньше времени, Reflection, как правило, не нужно. – jmcilhinney

ответ

1

Приведенные данные:

MainClass mainClass = new MainClass(); 
mainClass.listObj1 = new List<Class1>() 
{ 
    new Class1() { 
     dictObj2 = new Dictionary<int,Class2>() { 
      { 1, new Class2() { MeasurementA = 2.0, MeasurementB = 3.0, MeasurementC = 4.0 }}, 
      { 2, new Class2() { MeasurementA = 5.0, MeasurementB = 6.0, MeasurementC = 7.0 }} 
     } 
    } 
}; 

вы можете написать с помощью LINQ:

var fields = typeof(Class2) 
      // Get Properties of the ClassB 
      .GetProperties(BindingFlags.Public | BindingFlags.Instance) 
      // Map each PropertyInfo into collection of its values from c1.dictObj2 
      .SelectMany(pi => mainClass.listObj1 
             .SelectMany(c1 => c1.dictObj2) 
             .Select(p => new 
               { 
                Property = pi.Name, 
                Value = pi.GetValue(p.Value) 
               })) 
      // Group data with respect to the PropertyName 
      .GroupBy(x => x.Property, x => x.Value) 
      // And create proper dictionary 
      .ToDictionary(x => x.Key, x => x.ToList()); 

и теперь у Вас есть Dictionary с ключами ClassB имен свойств и значений как List этих значений свойств.

+0

Благодарю вас за ответ. Если для возвращаемого словаря также требуется CompositeKey (ключ, основанный на именах свойств Class2 и свойствах класса 1, например Struct (c1.PropA, c1.PropB, dict.PropName)), как это можно извлечь? – shansen

1

эффективно определяют свойства внутреннего класса (Class 2)

Независимо от эффективности, действительно есть только один способ, которым Вы можете сделать это (предполагая, что вы имеете в виду во время выполнения), и это используя Reflection.

петли через свойства внутреннего класса (класс 2)

foreach (var prop in instance.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) 
{ 
    Console.WriteLine(prop.Name); 
} 

цикл по коллекции объектов class1 (listObj1) выбора всех экземпляров собственности class2

foreach (var obj in mainClass.listObj1) 
{ 
    var innerClasses = obj.dictObj2.Values; 
    // do something with inner classes 
} 

вывести коллекцию свойства Class2 (например, первая итерация вернет коллекцию MeasurementA, по одному от каждого объекта Class1).

foreach (var prop in typeof(Class2).GetProperties(BindingFlags.Public | BindingFlags.Instance)) 
{ 
    foreach (var obj in mainClass.listObj1) 
    { 
     foreach (var innerClass in obj.dictObj2.Values) 
     { 
      Console.WriteLine(prop.GetValue(innerClass, null)); 
     } 
    } 
} 

Не знаю, почему вы так заинтересованы в использовании LINQ здесь, я думаю, несколько простых for петель все, что вам нужно здесь.

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