Übergeben einer Ausdrucksbaumstruktur als Parameter an eine andere Ausdrucksbaumstruktur

c# expression-trees lambda

Frage

Ich habe zwei Ausdrucksbäume wie folgt definiert:

private Expression<Func<TEntity, TPropertyResult>> PropertyAccessor { get; set; }

und

private Expression<Func<TPropertyResult, bool>> TestExpression { get; set; }

Ich muss einen neuen Ausdrucksbaum erstellen, der zu folgendem führt:

var expression = p => this.TestExpression(this.PropertyAccessor(p));

Bei Verwendung von Expression.Invoke(this.TestExpression, this.PropertyAccessor) ich den folgenden Fehler

{"Ausdruck vom Typ 'System.Func`2 [MyEntity, System.String]' kann nicht für Parameter vom Typ 'System.String'"} verwendet werden

TPropertyResult ist eine Zeichenfolge während meines Tests.

Ich habe versucht mit Expression.Call oder Expression.Invoke . Kein Glück. Was soll ich verwenden?

Akzeptierte Antwort

Ich denke, das macht das, wonach du verlangst:

Expression<Func<TEntity, bool>> Combined
{
    get
    {
        var entity = Expression.Parameter(typeof(TEntity));
        var pa = Expression.Invoke(PropertyAccessor, entity);
        var te = Expression.Invoke(TestExpression, pa);
        return (Expression<Func<TEntity, bool>>) Expression.Lambda(te, entity);
    }
}

Ich habe das getestet und es funktioniert so, wie ich es erwarten würde.

Wenn ich jedoch Ihre ursprüngliche Frage noch einmal lese (vor meinen Änderungen), habe ich den Eindruck, dass Sie die falsche Frage gestellt haben und wahrscheinlich keine Ausdrucksbäume benötigen. Wenn Sie nur Funktionen benötigen, können Sie sie ohne Expression :

private Func<TEntity, TPropertyResult> PropertyAccessor { get; set; }
private Func<TPropertyResult, bool> TestExpression { get; set; }
private Func<TEntity, bool> Combined
{
    get
    {
        return entity => TestExpression(PropertyAccessor(entity));
    }
}

Anwendungsbeispiel:

// Set up the original functions
PropertyAccessor = entity => GenerateResult(entity);
TestExpression = result => result.IsCool();

// This stores a reference to the combined function
var fn = Combined;

// This actually evaluates the function
bool isCool = fn(myEntity);

// Alternatively, you could evaluate the function directly, without the variable
bool isCool = Combined(myEntity);


Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow