Konvertieren von Funktion in Prädikat mithilfe von Reflektion in C #

c# expression-trees predicate reflection

Frage

Ich versuche im Grunde zu tun dies , aber ich weiß nicht , was T wird, so baue ich die Dinge mit Reflexion und Expression Bäume.

// Input (I don't know about "Book")
Type itemType = typeof(Book);

// Actual Code
// Build up func p => p.AuthorName == "Jon Skeet"
ParameterExpression predParam = Expression.Parameter(itemType, "p");
Expression left = Expression.Field(predParam, itemType.GetField("AuthorName"));
Expression right = Expression.Constant("Jon Skeet", typeof(string));
Expression equality = Expression.Equal(left, right);
Delegate myDelegate = Expression.Lambda(equality, new ParameterExpression[] { predParam }).Compile(); // Not sure if I need this

// Build up predicate type (Predicate<Book>)
Type genericPredicateType = typeof(Predicate<>);
Type constructedPredicateType = genericPredicateType.MakeGenericType(new Type[] { itemType });

// I need an instance to use this predicate, right? (** This Fails **)
object predicateInstance = Activator.CreateInstance(constructedPredicateType, new object[] { myDelegate });

Grundsätzlich habe ich eine List<Book> , über die ich nachzudenken versuche und die Find Methode Invoke . Die Find Methode benötigt ein Predicate<Book> anstelle von Func<Book, bool> , und ich habe mir für ein paar Stunden den Kopf dagegen geschlagen.

Edit: Hier ist der erste Teil der Fehler-Trace:

System.MissingMethodException: Constructor on type 'System.Predicate`1[[MyProject.Book, MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' not found.

Akzeptierte Antwort

Zum Glück ist das ziemlich einfach, indem Sie Ihren Aufruf von Expression.Lambda ändern:

Type predicateType = typeof(Predicate<>).MakeGenericType(itemType);
LambdaExpression lambda = Expression.Lambda(predicateType, equality, predParam);
Delegate compiled = lambda.Compile();

Es ist nicht klar, was Sie mit dem Ergebnis tun sollten, wohlgemerkt ... wenn die schwach typisierte Version für Sie in Ordnung ist, sollte das in Ordnung sein.


Beliebte Antwort

Nicht sicher, ob das das gleiche wie Jons Antwort ist:

public static Predicate<T> GetPredicate<T>()
{
    Type itemType = typeof(T);
    ParameterExpression predParam = Expression.Parameter(itemType, "p");
    Expression left = Expression.Field(predParam, itemType.GetField("AuthorName"));
    Expression right = Expression.Constant("Jon Skeet", typeof(string));
    Expression equality = Expression.Equal(left, right);
    Func<T, bool> function = (Func<T, bool>)Expression.Lambda(equality, new[] { predParam }).Compile();
    return new Predicate<T>(function);
}


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