Reputation: 131
In the past few days I've been trying to find a way to iterate on a List<dynamic>
without much success.
That's what I'm 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>
then in my controller I'm getting data back with:
dynamic irionErrorsExport = oracleDbManager.GetStrCtrlNDGWithErrors(tableName, queryParamsList, periodo, "", "", "");
and now I'm stuck since I need to iterate on irionErrorsExport and create a "concrete" object/s to use with EPPlus.
Can anyone please tell me if it is even possible and show a simple example?
Upvotes: 4
Views: 4986
Reputation: 111920
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's better if your method simply returns a List<IDictionary<string, object>>
, no dynamic
necessary.
Reflection on dynamic types is hard. Unless you can use duck typing (duck typing is when you know that the object can Duck()
, even if you don't know what exactly it's, so you can do dynamic x = something; x.Duck();
), then it's only semi-hard. If you don't trust me on this, you can try reading How do I reflect over the members of dynamic object?
Upvotes: 0
Reputation: 125650
Yes, you can iterate over dynamic
object:
dynamic source = new List<int>() {1, 2, 3, 4, 5, 6};
foreach (var item in source)
{
Console.Write(item.ToString());
}
Prints 123456
into console.
However, it will cause runtime exception if iteration is not possible:
Consider following code:
dynamic source = 2;
foreach (var item in source)
{
Console.Write(item.ToString());
}
RuntimeBinderException
is being thrown:
Cannot implicitly convert type 'int' to 'System.Collections.IEnumerable'
Edit: you should be aware of the differences between foreach
on normal variables and dynamic
. They are explained in another SO question: C# 4.0 'dynamic' and foreach statement
Upvotes: 2
Reputation: 35363
If you fill a DataTable
like here, You can use Json.Net and get a concrete object easily
//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; }
}
Upvotes: 1