表达式调用Any方法会抛出异常

8

我正在开发一个利用表达式的过滤机制,但是不知道如何使用Expression.Call方法调用Any方法。以下示例虽然没有意义,但说明了我的问题:

var person = new List<String>(new[] { "Peter", "John", "Jim" });
var personQuery = person.AsQueryable();

var anyMethod = typeof(Queryable).GetMethods().FirstOrDefault(method => method.Name == "Any" && method.GetParameters().Count() == 2);

Expression<Func<String, bool>> expr = p => p == "Amy";

// person.Any(person => person == "Amy"
var call = Expression.Call(
    anyMethod,
    personQuery.Expression,
    expr
);

Expression.Call会抛出ArgumentException异常:

System.ArgumentException was unhandled
  HResult=-2147024809
  Message=Method Boolean Any[TSource](System.Linq.IQueryable`1[TSource], System.Linq.Expressions.Expression`1[System.Func`2[TSource,System.Boolean]]) is a generic method definition.
  Source=System.Core
  StackTrace:
       w System.Linq.Expressions.Expression.ValidateMethodInfo(MethodInfo method)
       w System.Linq.Expressions.Expression.ValidateMethodAndGetParameters(Expression instance, MethodInfo method)
       w System.Linq.Expressions.Expression.Call(MethodInfo method, Expression arg0, Expression arg1)
       w TestConsoleApplication.Program.Main(String[] args) w d:\Users\user\Documents\Visual Studio 2012\Projects\TestConsoleApplication\TestConsoleApplication\Program.cs:wiersz 26
       w System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       w System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       w Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       w System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       w System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       w System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       w System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       w System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

2
你能为我们将异常信息文本翻译成英文吗? - Jon Skeet
异常消息已翻译。 - PaulP
1个回答

15

你的anyMethod变量将包含通用方法的定义,即Any<TSource>。在调用它之前,你需要将其转换为Any<String>

你可以通过调用anyMethod.MakeGenericMethod并提供typeof(String)参数来实现此目的。因此,你的代码变成了:

var person = new List<String>(new[] { "Peter", "John", "Jim" });
var personQuery = person.AsQueryable();

var anyMethod = typeof(Queryable).GetMethods().FirstOrDefault(method => method.Name == "Any" && method.GetParameters().Count() == 2);
var specificMethod = anyMethod.MakeGenericMethod(typeof(String));//<--Important
Expression<Func<String, bool>> expr = p => p == "Amy";

// person.Any(person => person == "Amy"
var call = Expression.Call(
    specificMethod,
    personQuery.Expression,
    expr
);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接