是否可以对List<;动态>;

本文关键字:lt 动态 gt List 是否 | 更新日期: 2023-09-27 18:27:09

在过去的几天里,我一直试图找到一种在List<dynamic>上迭代的方法,但没有取得多大成功。

这就是我正在做的:

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);
}

上面的代码是一个返回IEnumerable<dynamic>的方法,然后在我的控制器中,我用获取数据

dynamic irionErrorsExport = oracleDbManager.GetStrCtrlNDGWithErrors(tableName, queryParamsList, periodo, "", "", "");

现在我陷入了困境,因为我需要迭代irionErrorsExport并创建一个与EPPlus一起使用的"具体"对象。

有谁能告诉我这是否可能,并举一个简单的例子吗?

是否可以对List<;动态>;

是的,您可以迭代dynamic对象:

dynamic source = new List<int>() {1, 2, 3, 4, 5, 6};
foreach (var item in source)
{
    Console.Write(item.ToString());
}

123456打印到控制台中。

然而,如果迭代不可能,它将导致运行时异常:

考虑以下代码:

dynamic source = 2;
foreach (var item in source)
{
    Console.Write(item.ToString());
}

正在抛出RuntimeBinderException

无法将类型"int"隐式转换为"System.Collections.IEnumerable"

编辑:您应该注意正常变量上的foreachdynamic之间的差异。它们在另一个SO问题中得到了解释:C#4.0的"动态"和foreach语句

如果您像这里一样填写DataTable,您可以使用Json.Net轻松获得具体对象

//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; }
}
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);
}

从调用方法来看,你"作弊"了。您知道您的动态收藏是ExpandoObject,因此

foreach (IDictionary<string, object> row in result)
{
    foreach (var kv in row)
    {
        Console.WriteLine("{0}: {1}", kv.Key, kv.Value);
    }
}

最后,如果您的方法只是返回一个List<IDictionary<string, object>>,而不需要dynamic,那会更好。

对动态类型的反思很难。除非你可以使用duck类型(duck类型是指你知道对象可以Duck(),即使你不知道它到底是什么,所以你可以使用dynamic x = something; x.Duck();),否则它只是半硬的。如果你对此不信任我,你可以试着阅读《我如何反思动态对象的成员?