【问题标题】:Dynamic Link, changing a property for every item in a list动态链接,更改列表中每个项目的属性
【发布时间】:2011-10-31 07:13:27
【问题描述】:

动态地,我想采用像“GPARank”这样的字符串属性并更改它的值。

通常情况下,我会

var rank = gpa.ForEach(x => x.GPARank = i);

但在这种情况下,我不知道我在编译时更改了哪个属性。我试图在Dynamic LINQ OrderBy on IEnumerable<T> 修改 Marc Gravell 的代码以供我使用,但我的大脑爆炸了。

谢谢!

想通了使用反射,仍然想要一个动态 linq 表达式解决方案

gpa.ForEach(x => x.GetType().GetProperty(_ColumnRank).SetValue(x, i += 1 , null));

我能够弄清楚如何使用反射来做到这一点。但是,如果有人有时间或希望向我展示如何使用带有运行时表达式的动态 linq 来做到这一点,我真的很想知道如何做到这一点。

【问题讨论】:

  • 你“在编译时不知道你在改变哪个属性”是怎么来的?
  • 我有一个包含 20 多个 Ranked Properties 的课程,当用户过滤并重新排序时,我想使用 linq 执行此操作,而不是访问数据库。
  • 我对键盘上的大脑飞溅不承担任何责任。接下来,LINQ 主要是查询,而不是变异。在 4.0 中,Expression 确实允许赋值,但简单的委托会容易得多。我现在不在 PC 上,但如果您愿意,我可以在明天添加一个委托版本。我不确定 Expression 版本是否值得,因为 AFAIK 没有提供者会使用它,所以它最终只不过是一种棘手的委托方式。
  • @MarcGravell 是的,我希望看到此代码用于教育目的。谢谢
  • @bladefist 哪个?前几天晚上我添加了一个委托版本(未经测试)......

标签: c# linq lambda


【解决方案1】:

伪代码,未经测试:

string propName = "GPARank";  
PropertyInfo prop = typeof(Item).GetProperty(propName);
Action<Item,string> setter = (Action<Item,string>)Delegate.CreateDelegate(
    typeof(Action<Item,string>), prop.GetSetMethod());
foreach(Item obj in list) setter(obj,newValue);

说实话,在大多数情况下,直接使用 PropertyInfo(通过 SetValue)就可以了;在这种情况下,我对您的原始代码所做的唯一更改是将获取 PropertyInfo 在循环之外,而不是每个项目。

【讨论】:

  • 感谢您的回复。这东西很有趣。
猜你喜欢
  • 2016-06-23
  • 2012-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-04
  • 2013-02-07
  • 1970-01-01
相关资源
最近更新 更多