1

Dynamically, I would like to take a string property like "GPARank" and change the value of it.

normally, I would have

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

But in this case, I don't know which property I am changing at compile time. I tried to modify Marc Gravell's code at Dynamic LINQ OrderBy on IEnumerable<T> for my uses, but my brain exploded.

Thanks!

Figured out using reflection, still want a dynamic linq expressions solution

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

I was able to figure out how to do this using reflection. But if anyone has the time or desire to show me how to do this using dynamic linq with run-time expressions, I would really like to know how to do this.

Community
  • 1
  • 1
bladefist
  • 1,054
  • 3
  • 13
  • 23
  • How does it come that you "don't know which property you are changing at compile time"? – GianT971 Oct 30 '11 at 21:53
  • I have a class with 20+ Ranked Properties, as the user filters down and re-orders, I would like to do this using linq and not hit the database. – bladefist Oct 30 '11 at 21:56
  • I accept no responsibility for brain-spatter on keyboards. Next, LINQ is primarily query, not mutation. In 4.0, Expression does allow assignment, but a simple delegate would be much easier. I'm not at a PC right now, but I can add a delegate version tomorrow if you would like. I'm not sure the Expression version is worthwhile, since AFAIK no provider will use it, so it is ultimately nothing more than a tricky way to make a delegate. – Marc Gravell Oct 30 '11 at 23:04
  • @MarcGravell Yes, I'd like to see this code for educational purposes. Thanks – bladefist Oct 31 '11 at 19:09
  • @bladefist which? I added a delegate version (untested) the other night... – Marc Gravell Oct 31 '11 at 19:38
  • @MarcGravell Ah, I just got the timeline messed up and thought you wanted to do yet another solution. I was a bit confused too. Anyway, thanks for what you wrote up. – bladefist Oct 31 '11 at 19:55

1 Answers1

1

Pseudo-code, untested:

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

To be honest though, in most cases just using the PropertyInfo directly (via SetValue) will work; the only change I would make to your original code in that case would be to move obtaining the PropertyInfo outside the loop, rather than per-item.

Marc Gravell
  • 927,783
  • 236
  • 2,422
  • 2,784