Wie lege ich einen Feldwert in einem C # -Ausdrucksbaum fest?

c# expression-trees lambda

Frage

Gegeben:

FieldInfo field = <some valid string field on type T>;
ParameterExpression targetExp = Expression.Parameter(typeof(T), "target");
ParameterExpression valueExp = Expression.Parameter(typeof(string), "value");

Wie kompiliere ich einen Lambda-Ausdruck, um das Feld auf dem Parameter "target" auf "value" zu setzen?

Akzeptierte Antwort

.Net 4.0 : Jetzt, wo es Expression.Assign , ist das einfach zu machen:

FieldInfo field = typeof(T).GetField("fieldName");
ParameterExpression targetExp = Expression.Parameter(typeof(T), "target");
ParameterExpression valueExp = Expression.Parameter(typeof(string), "value");

// Expression.Property can be used here as well
MemberExpression fieldExp = Expression.Field(targetExp, field);
BinaryExpression assignExp = Expression.Assign(fieldExp, valueExp);

var setter = Expression.Lambda<Action<T, string>>
    (assignExp, targetExp, valueExp).Compile();

setter(subject, "new value");

.Net 3.5 : Sie können nicht, Sie müssen stattdessen System.Reflection.Emit verwenden:

FieldInfo field = typeof(T).GetField("fieldName");
ParameterExpression targetExp = Expression.Parameter(typeof(T), "target");
ParameterExpression valueExp = Expression.Parameter(typeof(string), "value");

// Expression.Property can be used here as well
MemberExpression fieldExp = Expression.Field(targetExp, field);
BinaryExpression assignExp = Expression.Assign(fieldExp, valueExp);

var setter = Expression.Lambda<Action<T, string>>
    (assignExp, targetExp, valueExp).Compile();

setter(subject, "new value");

Expertenantwort

Das Setzen eines Feldes ist, wie bereits diskutiert, problematisch. Sie können (in 3.5) eine einzelne Methode, zB einen Property-Setter - aber nur indirekt. Dies wird in 4.0, wie hier besprochen, viel einfacher. Wenn Sie jedoch tatsächlich Eigenschaften (keine Felder) haben, können Sie einfach mit Delegate.CreateDelegate viel tun:

using System;
using System.Reflection;
public class Foo
{
    public int Bar { get; set; }
}
static class Program
{
    static void Main()
    {
        MethodInfo method = typeof(Foo).GetProperty("Bar").GetSetMethod();
        Action<Foo, int> setter = (Action<Foo, int>)
            Delegate.CreateDelegate(typeof(Action<Foo, int>), method);

        Foo foo = new Foo();
        setter(foo, 12);
        Console.WriteLine(foo.Bar);
    }
}



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum