public static void SetData(ScriptResult result, object item, string key) { //item can be: // 1) a single normal object // 2) a collection of normal objects // 3) a single IDictionary object that contains key value pairs that are like property name/values // 4) a collection of IDictionary objects like #3 if (!(item is IEnumerable list)) { list = new object[] { item } } ; //item is #1, a single object so make a collection //list is now #2, #3, or #4 if (list is IDictionary itemDictionary) { list = new IDictionary[] { itemDictionary } } ; //list is #3, a single IDictionary object so make a collection //list is now #2 or #4 if (!result.DataSet.ContainsKey(key)) { result.DataSet.Add(key, new ScriptData()); } ScriptData data = result.DataSet[key]; foreach (object i in list) { //list is a collection of objects that are either a normal object with properites or a //dictionary with key value pairs (key is the property name, value is the propety value) //in either case we want each item in list to be a dictionary with string keys and object values IDictionary <object, object> dict = new Dictionary <object, object>(); itemDictionary = i as IDictionary; if (itemDictionary == null) { //i is a normal object, not a dictionary PropertyInfo[] pinfos = i.GetType().GetProperties(); foreach (PropertyInfo p in pinfos) { string name = p.Name; object val = p.GetValue(i, null); dict.Add(name, val); } } else { //i is a dictionary object foreach (var k in itemDictionary.Keys) { string name = k.ToString(); object val = itemDictionary[k]; dict.Add(name, val); } } data.AddItem(dict); } }