2013-03-08 6 views
14

J'ai donc récemment joué avec la construction dynamique d'arbres d'expression et je suis tombé sur cette méthode, qui me semble un peu étrange. Au début, je pensais « oh cool C'est exactement ce que je dois » après le code écrit en permanence le long des lignes deExpression.Bind() - que fait-il réellement?

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

Oui, je sais qu'il ya Expression.PropertyOrField() appel, mais il ne aller-retour pour revenir à la réflexion pour trouver membre par nom , où j'ai généralement déjà MemberInfo instance.

Donc de toute façon, je pensais que Expression.Bind() serait utile pour moi, mais il fait quelque chose que je ne comprends pas vraiment. Vu le code suivant:

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

public class Foo 
{ 
    public string Bar; 
} 

il produit MemberAssignment expression Bar = "". Mais il n'y a pas d'instance et pas de référence statique. Comment pourrais-je jamais appliquer cette expression à et l'instance de Foo? Je ne trouve aucun exemple de cette méthode utilisée.

Répondre

14

Expressions d'initiateur d'objet.

Disons que vous avez eu:

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

Ensuite, vous pouvez faire:

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

qui est quelque chose comme:

i => new Foo { Property = i } 

Vieux:

je peux » t vous aider s olve le "problème de performance" que vous êtes déterminé à résoudre (l'utilisation d'Expression.PropertyOrField introduira-t-elle vraiment un goulot d'étranglement dans votre application? Je suis un peu sceptique. Vous devriez le déterminer avant d'effectuer une optimisation prématurée) (EDIT: Toutes nos excuses pour avoir supposé que c'était une optimisation de perf, et comme vous l'avez découvert vous-même, Expression.MakeMemberAccess est ce dont vous avez besoin), mais peut vous dire ce Expression.Bind est utile pour.

+2

oooh ... Je pensais que c'était ça, mais je m'attendais à une surcharge de 'Expression.New()' pour l'accepter. Cela ne m'est pas venu à l'esprit que ce pourrait être un appel totalement différent. –

+0

En ce qui concerne ne pas utiliser 'PropertyOrField': ce n'est pas vraiment l'optimisation. Plus comme pour ma propre santé mentale. –

+0

Ah, si c'est le cas, alors pourquoi ne pas écrire un petit assistant qui prend un 'MemberInfo' et des branches le cas échéant? – Ani

Questions connexes