Expression.Bind() - what does it actually do?
Asked Answered
C

1

17

So I've been playing with dynamically building expression trees lately and came across this method, which seems kinda odd. At first I thought "oh cool this is exactly what I need" after constantly writing code along the lines of

var left = member is FieldInfo ? Expression.Field(instance, (FieldInfo)member) : Expression.Property(instance, (PropertyInfo)member);
var right = ...
var assign = Expression.Assign(left, right);

Yes, I know there is Expression.PropertyOrField() call, but it does roundtrip back to reflection to find member by name, where as I typically already have MemberInfo instance.

So anyway, I thought Expression.Bind() would be useful to me, but it does something I don't really understand. Given the following code:

void Main()
{
    var m = typeof(Foo).GetField("Bar");
    Expression.Bind(m, Expression.Constant("")).Dump();
}

public class Foo
{
    public string Bar;
}

it produces MemberAssignment expression Bar = "". But there is no instance and no static reference. How would I ever apply this expression to and instance of Foo? I can't find any example of this method being used.

Cinerama answered 8/3, 2013 at 15:52 Comment(0)
A
15

Object-Initializer expressions.

Let's say you had:

public class Foo
{
    public int Property { get; set; }
}

Then you could do:

var parameter = Expression.Parameter(typeof(int), "i");
var newExpr = Expression.New(typeof(Foo));
var bindExprs = new[]
    {
        Expression.Bind(typeof(Foo).GetProperty("Property"), parameter)
        // You can bind more properties here if you like.
    };

var body = Expression.MemberInit(newExpr, bindExprs);
var lambda = Expression.Lambda<Func<int, Foo>>(body, parameter);

which is something like:

i => new Foo { Property = i } 

Old:

I can't help you solve the "performance issue" you are determined to solve (will using Expression.PropertyOrField really introduce a bottleneck in your application? I'm somewhat skeptical. You should determine this before optimizing prematurely) (EDIT: Apologies for incorrectly assuming that this was a perf optimization, and as you've found out yourself, Expression.MakeMemberAccess is what you need), but I can tell you what Expression.Bind is useful for.

Ahead answered 8/3, 2013 at 16:9 Comment(6)
oooh... I thought that is what it is, but I was expecting an overload of Expression.New() to accept that. It didn't occur to me that could be a totally different call.Cinerama
Regarding not using PropertyOrField: that is not really optimization. More like for my own sanity.Cinerama
Ah, if that's the case, then why not write a little helper that takes a MemberInfo and branches as appropriate?Ahead
I have... it just seems like a very common operation that should have a standard implementation.Cinerama
Fair enough; apologies for jumping to conclusions!Ahead
Incidentally... apparently there is this thing Expression.MakeMemberAccess, which does exactly what I need... hangs head in shameCinerama

© 2022 - 2024 — McMap. All rights reserved.