Expression.Bind () - cosa fa in realtà?

.net c# expression expression-trees reflection

Domanda

Quindi ultimamente ho giocato con gli alberi di espressione dinamicamente costruendo e ho trovato questo metodo, che mi sembra abbastanza strano. All'inizio ho pensato "oh questo è esattamente ciò di cui ho bisogno" dopo aver scritto costantemente il codice lungo le linee

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

Sì, so che esiste la chiamata a Expression.PropertyOrField() , ma fa il roundtrip di nuovo alla reflection per trovare membro per nome, dove di solito ho già un'istanza MemberInfo .

Ad ogni modo, pensavo che Expression.Bind() sarebbe stato utile per me, ma fa qualcosa che non capisco davvero. Dato il seguente codice:

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

public class Foo
{
    public string Bar;
}

produce MemberAssignment espressione MemberAssignment Bar = "" . Ma non c'è istanza e nessun riferimento statico. Come potrei mai applicare questa espressione a e istanza di Foo ? Non riesco a trovare alcun esempio di questo metodo in uso.

Risposta accettata

Espressioni di inizializzazione dell'oggetto .

Diciamo che hai avuto:

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

Quindi potresti fare:

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

che è qualcosa come:

i => new Foo { Property = i } 

Vecchio:

Non posso aiutarti a risolvere il "problema di prestazioni" che sei determinato a risolvere (userò Expression.PropertyOrField davvero introdurrà un collo di bottiglia nella tua applicazione? Sono un po 'scettico. Dovresti determinarlo prima di ottimizzarlo prematuramente) ( MODIFICA : Scuse per assumendo erroneamente che si trattava di un'ottimizzazione perfetta e, come hai scoperto tu stesso, Expression.MakeMemberAccess è ciò di cui hai bisogno), ma posso dirti a cosa è utile Expression.Bind .



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché