[转载]c#利用dynamic解决匿名对象不能赋值的问题

[转载]利用dynamic解决匿名对象不能赋值的问题 – L.Qiu – 博客园.

匿名对象是.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是等价的,这为我们开发带来了很大的灵活性,但这样做的性能开销目前还没有深入研究,如果有哪位朋友测试过,也请告知,谢谢。

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏