zoukankan      html  css  js  c++  java
  • 利用dynamic解决匿名对象不能赋值的问题

    关于匿名对象

    匿名对象是.Net Framework 3.0提供的新类型,例如:

    var obj = { Name = "aa", Value = 1 };

    就是一个匿名类,搭配Linq,可以很灵活的在代码中组合数据,例如:

    var r = from p in DbContext.Actions 
        select new
          A = p.Name, 
          B = p.Text 
        };

    特殊需求:给匿名对象属性赋值

    但有时候会有一些特殊的要求,需要给获取的匿名对象的某些属性进行赋值,例如如下的代码:

    //根据上例使用LINQ获取的结果集
    foreach(var item in r)
    {
    item.A = "new name";
    }

    以上这段代码在运行时,会抛出异常“该对象的属性是只读的”。说明匿名类在内部实现上,只能在初始化的时候赋值,如果想再次改变,对不起,这样是不可以的。

    解决方案

    但有的时候确实是有这样的需求,那有什么方法可以解决呢? 经过研究,发现可以采用如下的方案解决,本人已经验证通过。

    答案就是使用C# 4.0里面新提供的动态类型:dynamic
      直接上代码,想必大家一看就明白了:

    //声明dynamic泛型集合
    List<dynamic> newpayList = new List<dynamic>();
    payList.ForEach(t => {
    //new 一个ExpandoObject对象
    dynamic d = new System.Dynamic.ExpandoObject();
    d.IntervalDay = 0;
    d.Percent = Math.Round(t.Amount / totalRevenue, 4);
    d.Amount = adjAmount * Math.Round(t.Amount / totalRevenue, 4);
    d.PayDate = t.EstPaymentDate;
    d.IsLast = false;
    newpayList.Add(d);
    });

    var count = newpayList.Count();
    for (int i = 0; i < count; i++)
    {
    var item = newpayList[i];
    if (i != 0) {
    //改变动态类型的属性值
    item.IntervalDay = (item.PayDate - newpayList[i - 1].PayDate).Days;
    }
    if( i == count - 1)
    item.IsLast = true;
    }

    用动态类型取代匿名对象,但实际上,它们之间又有着紧密的联系,在某些时候,匿名对象和dynamic是等价的,这为我们开发带来了很大的灵活性,但这样做的性能开销目前还没有深入研究,如果有哪位朋友测试过,也请告知,谢谢。

  • 相关阅读:
    git fetch, git pull, git pull -rebase区别
    Git 变更远程仓库地址
    终于有人把 Docker 讲清楚了,万字详解!
    Harbor install and used
    访问gitlab从http方式改为ssh方式,gitlab使用的不是标准22端口
    Linux下的ifconfig已经过时了,试试ip命令
    在CentOS 8上使用DNF管理软件包
    搭建hadoop的HA集群模式(hadoop2.7.3+hive+spark)
    spark运行时加载配置文件(hive,hdfs)
    java 如何用pattern 和 Matcher 来使用正则表达式(一)
  • 原文地址:https://www.cnblogs.com/qiuliang/p/2356272.html
Copyright © 2011-2022 走看看