在 C# 中使用反射将 func 转换为谓词
我基本上试图做这个,但我不这样做知道 T 是什么,所以我使用反射树和表达式树来构建东西。
// 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 });
基本上,我有一个 List
,我试图对其进行反思并Invoke
它的 Find
方法。 Find
方法需要一个 Predicate
而不是 Func
,我一直在努力反对这一点几个小时。
编辑:这是错误跟踪的第一部分:
System.MissingMethodException: Constructor on type 'System.Predicate`1[[MyProject.Book, MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' not found.
I'm basically trying to do this, but I don't know what T will be, so I'm building things up using Reflection and Expression trees.
// 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 });
Basically, I have a List<Book>
, which I'm trying to reflect on and Invoke
its Find
method. The Find
method needs a Predicate<Book>
instead of Func<Book, bool>
, and I've been beating my head against this for a few hours.
Edit: Here is the first part of the error trace:
System.MissingMethodException: Constructor on type 'System.Predicate`1[[MyProject.Book, MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' not found.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
幸运的是,这很容易做到,只需更改对
Expression.Lambda
的调用即可:目前尚不清楚您需要对结果做什么,请注意...如果弱类型版本没问题的话对你来说,那应该没问题。
Fortunately this is pretty easy to do, just by changing your call to
Expression.Lambda
:It's not clear what you needed to do with the result, mind you... if the weakly-typed version is okay for you, that should be fine.
不确定这是否与乔恩的回答相同:
Not sure if this is the same as Jon's answer: