This morning i came uppon which seemed a simple problem to solve. I wanted to write all values of a list into my console. In this case, the List contains List Members. I've been searching for a solution for some time now but I couldn't find one.
I've made it so far.
tl.ForEach(tradelane =>
{
row = "";
foreach(PropertyInfo pi in typeof(coTradeLane).GetProperties())
{
Type T = pi.PropertyType;
if (T.IsGenericType && T.GetGenericTypeDefinition() == typeof(List<>))
{
foreach(PropertyInfo piList in tradelane.GetType().GetProperties())
{
// Select the nested list and loop through each member..
}
continue;
}
var val = pi.GetValue(tradelane);
if (val != null) row += val.ToString() + " \t ";
else row += " \t \t ";
}
Console.WriteLine(row);
});
I'm not entirely sure what you want, but this recursive solution may help you on your way.
I have cheated slightly because I'm looking for IList
rather than List<T>
to simplify the code.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Demo
{
// This type contains two properties.
// One is a plain List<Double>, the other is a type that itself contains Lists.
public sealed class Container
{
public List<double> Doubles { get; set; }
public Lists Lists { get; set; }
}
// This type contains two Lists.
public sealed class Lists
{
public List<string> Strings { get; set; }
public List<int> Ints { get; set; }
}
public static class Program
{
private static void Main()
{
var lists = new Lists
{
Strings = new List<string> {"A", "B", "C"},
Ints = new List<int> {1, 2, 3, 4, 5}
};
var container = new Container
{
Doubles = new List<double> {1.1, 2.2, 3.3, 4.4},
Lists = lists
};
var items = FlattenLists(container);
// This prints:
//
// 1.1
// 2.2
// 3.3
// 4.4
// A
// B
// C
// 1
// 2
// 3
// 4
// 5
foreach (var item in items)
Console.WriteLine(item);
}
// This recursively looks for all IList properties in the specified object and its subproperties.
// It returns each element of any IList that it finds.
public static IEnumerable<object> FlattenLists(object container)
{
foreach (var pi in container.GetType().GetProperties().Where(p => p.GetMethod.GetParameters().Length == 0))
{
var prop = pi.GetValue(container);
if (typeof(IList).IsAssignableFrom(pi.PropertyType))
{
foreach (var item in (IList) prop)
yield return item;
}
foreach (var item in FlattenLists(prop))
yield return item;
}
}
}
}
I'm not sure how much use this is though, since you just get a flattened list of object
with no idea of the property with which they are associated. You could, however, modify FlattenLists()
to return more information than just the object.