I have a design where class holds a List<> of Summary objects, and each Summary is a dictionary of semi-dynamic properties. That is, every Summary in a given list will have the same keys in the dictionary. I'm using this design to build a set of dynamic "properties" to keep track of summary values since, per my project specs, these summary values will be configurable at runtime.
The question is: How can I flatten this List so that each item in the list is treated as-if the keys in the dictionary were actual properties?
I've tried different variations on converting the Dictionary to a list, but that seems inherently wrong since I really need to treat the keys as properties. I'm guessing I need to use the new dynamic feature of C# 4.0+ and the ExpandoObject, but I can't quite get it right.
The code below shows the basic setup, with "flattenedSummary" giving me what I want - a new list of a dynamic type whose properties are the keys of the Summary's dictionary. However, that is flawed in that I've hard-coded the property names and I can't do that since I won't really know them until runtime.
The flattenedSummary2 version attempts to flatten the list but falls short as the returned type is still a List and not the List that I want.
public class Summary : Dictionary<string, object>
{
}
public class ClassA
{
public List<Summary> Summaries = new List<Summary>();
}
static void Main(string[] args)
{
ClassA a = new ClassA();
var summary = new Summary();
summary.Add("Year", 2010);
summary.Add("Income", 1000m);
summary.Add("Expenses", 500m);
a.Summaries.Add(summary);
summary = new Summary();
summary.Add("Year", 2011);
summary.Add("Income", 2000m);
summary.Add("Expenses", 700m);
a.Summaries.Add(summary);
summary = new Summary();
summary.Add("Year", 2012);
summary.Add("Income", 1000m);
summary.Add("Expenses", 800m);
a.Summaries.Add(summary);
var flattenedSummary = from s in a.Summaries select new { Year = s["Year"], Income = s["Income"], Expenses = s["Expenses"] };
ObjectDumper.Write(flattenedSummary, 1);
var flattenedSummary2 = Convert(a);
ObjectDumper.Write(flattenedSummary2, 1);
Console.ReadKey();
}
public static List<ExpandoObject> Convert(ClassA a)
{
var list = new List<ExpandoObject>();
foreach (Summary summary in a.Summaries)
{
IDictionary<string, object> fields = new ExpandoObject();
foreach (var field in summary)
{
fields.Add(field.Key.ToString(), field.Value);
}
dynamic s = fields;
list.Add(s);
}
return list;
}