C#创建编译时动态属性对象和运行时动态属性对象(linq 动态列名)

void Main()
{
    var list = new List<object>();
    Enumerable.Range(1, 100).ToList().ForEach(item =>
    {
        dynamic d = new System.Dynamic.ExpandoObject();
        d.Name = "张三";
        d.Gender = item % 3 == 0 ? "" : "";
        (d as IDictionary<string, Object>).Add("Age", 30+item);
        list.Add(d);
    });
    
    list.Dump();

}

对于需要临时使用一个类型,却用不想定义一个类。或者前端绑定的动态列名的情况,也非常方便。

结果如下:

经验证,这种数据集可以直接绑定到 WPF,但绑定到 asp.net GridView 和 winform 的 DataGridView 一个报错一个没反应,那就转成DataTable吧,一个扩展方法就搞定了

public static class DynamicExtension
    {
        public static DataTable ToDataTable(this IEnumerable<dynamic> items)
        {
            var data = items.ToArray();
            if (data.Count() == 0) return null;

            var dt = new DataTable();
            foreach (var key in ((IDictionary<string, object>)data[0]).Keys)
            {
                dt.Columns.Add(key);
            }
            foreach (var d in data)
            {
                dt.Rows.Add(((IDictionary<string, object>)d).Values.ToArray());
            }
            return dt;
        }
    }

 dynamic 类型竟然支持序列化与反序列化:

    dynamic d = new ExpandoObject();
    d.Name = "张三";
    d.Gender = "";
    (d as IDictionary<string, Object>).Add("Age", 30);
    Console.WriteLine( Newtonsoft.Json.JsonConvert.SerializeObject(d));
    dynamic x = Newtonsoft.Json.JsonConvert.DeserializeObject<ExpandoObject>( Newtonsoft.Json.JsonConvert.SerializeObject(d));
    Console.WriteLine( x.Name);
    Console.WriteLine( x.Gender);
    Console.WriteLine( x.Age);

使用中发现ExpandoObject可以转为dynamic,但dynamic无法转换为ExpandoObject,切记不要相互转换,比如反序列化时选ExpandoObject,而不能选dynamic。

使用时还有一点需要注意,不要给dynamic无法识别的数据类型,如 null

posted on 2020-04-09 16:30  空明流光  阅读(759)  评论(0编辑  收藏  举报

导航