Is it possible to repeat in the <dynamic> list?
In the past few days, I have been trying to find a way to iterate over a List<dynamic> without much success.
What am I doing:
while (dr.Read()) { dynamic e = new ExpandoObject(); var d = e as IDictionary<string, object>; for (var i = 0; i < dr.FieldCount; i++) d.Add(dr.GetName(i), DBNull.Value.Equals(dr[i]) ? null : dr[i]); result.Add(e); } the above code is a method that returns an IEnumerable<dynamic> , and then in my controller I return the data with:
dynamic irionErrorsExport = oracleDbManager.GetStrCtrlNDGWithErrors(tableName, queryParamsList, periodo, "", "", ""); and now I'm stuck, since I need to iterate over irionErrorsExport and create a “concrete” object / s for use with EPPlus.
Can someone tell me if this is possible and give a simple example?
Yes, you can iterate over a dynamic object:
dynamic source = new List<int>() {1, 2, 3, 4, 5, 6}; foreach (var item in source) { Console.Write(item.ToString()); } Prints 123456 in the console.
However, this will result in a runtime exception if iteration is not possible:
Consider the following code:
dynamic source = 2; foreach (var item in source) { Console.Write(item.ToString()); } RuntimeBinderException :
Cannot implicitly convert type 'int' to 'System.Collections.IEnumerable'
Edit : You should know the differences between foreach for regular variables and dynamic . They are explained in another SO question: C # 4.0 'dynamic' and foreach statement
while (dr.Read()) { IDictionary<string, object> e = new ExpandoObject(); for (var i = 0; i < dr.FieldCount; i++) e.Add(dr.GetName(i), DBNull.Value.Equals(dr[i]) ? null : dr[i]); result.Add(e); } From the calling method, you “cheat”. You know that your dynamic collection is an ExpandoObject , so
foreach (IDictionary<string, object> row in result) { foreach (var kv in row) { Console.WriteLine("{0}: {1}", kv.Key, kv.Value); } } In the end, it is better if your method simply returns List<IDictionary<string, object>> , no dynamic .
Reflection of dynamic types is difficult. If you can’t use duck print (duck print is when you know that an object can duck Duck() , even if you don’t know what it is, so you can do dynamic x = something; x.Duck(); ) then it will only be semi-solid. If you do not trust me, you can try to read. How can I reflect the elements of a dynamic object?
If you fill out a DataTable as here , you can use Json.Net and easily get a specific object
//Sample DataTable DataTable dt = new DataTable(); dt.Columns.Add("IntCol"); dt.Columns.Add("StrCol"); dt.Rows.Add(new object[]{1,"1"}); dt.Rows.Add(new object[]{2,"2"}); var jsonstr = JsonConvert.SerializeObject(dt); var list = JsonConvert.DeserializeObject<List<YourClass>>(jsonstr); public class YourClass { public int IntCol { set; get; } public string StrCol { set; get; } }