Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
693 views
in Technique[技术] by (71.8m points)

c# - Using LINQ to loop through inner class properties in outer class collection

Leveraging off the Q&As dealing with looping through an object's properties (https://stackoverflow.com/questions/15586123/loop-through-object-and-get-properties, Loop Through An Objects Properties In C#), where you have:

  • a collection of Class1 objects (i.e. listObj1)
  • each Class1 contains a collection of Class2 objects (i.e. dictObj2)

How would you:

  • efficiently determine the properties of the inner class (Class2)
  • loop through the the properties of the inner class (Class2)
  • loop through the collection of Class1 objects (listObj1) selecting all instances of the the Class2 property
  • output the collection of Class2 property (e.g. the first iteration would return a collection of MeasurementA, one from each Class1 object).
  • and group the collection by Class1.PropertyA and Class1.PropertyB

Please find below a rough map of the classes involved.

I have been trying to use a LINQ query without success. Any ideas or guidance would be greatly appreciated.

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; }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Given data:

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 }}
        }
    }
};

you can write with 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());

and now you have a Dictionary with keys of ClassB property names and values as List of those properties values.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...