【发布时间】:2012-09-20 09:56:53
【问题描述】:
我有一个无法解决的 lambda 表达式树问题。我正在尝试制作动态 linq Select 语句。
我在这里创建了一个动态存储库:
private static dynamic GetRepository(Type type)
{
dynamic repository = typeof(IFactory).GetMethod("Create").MakeGenericMethod(typeof(IRepository<>).MakeGenericType(type)).Invoke(ObjectFactory.Instance, new object[] { });
return repository;
}
有了这个,我只需要在编译时调用它,我不知道 x 和 SomeProperty。我有带有 SomeProperty 名称的 PropertyInfo propertyInfo 和带有 x 类型的 Type objectType。 它在目标 1 处失败,但有以下例外:
GetMethod(字符串名称)处的 System.Reflection.AmbiguousMatchException
代码:
private SomeObject CreateSomeObject (PropertyInfo propertyInfo, Type objectType)
{
var param = Expression.Parameter(objectType, "x");
MemberExpression expression = Expression.PropertyOrField(param, propertyInfo.Name);
//Goal 1: var selectExpression = Expression.Lambda<Func<objectType, object>>(expression, param);
var selectExpression = typeof(Expression).GetMethod("Lambda").MakeGenericMethod(typeof(Func<,>)
.MakeGenericType(objectType, typeof(object)))
.Invoke((object)null, new object[] { expression, param });
// Goal 2: List<object> list = GetRepository(objectType).FindAllQuery().Select(x => x.SomeProperty).ToList();
List<object> list = GetRepository(objectType).FindAll().Select(selectExpression);
}
如何解决?
更新 1:
我更改了选择 Lambda 方法的方式,打包“param”参数的方式,并添加了一个对象转换器到“表达式”。
private SomeObject CreateSomeObject (PropertyInfo propertyInfo, Type objectType)
{
var param = Expression.Parameter(objectType, "x");
Expression expression = Expression.Convert(Expression.PropertyOrField(param, propertyInfo.Name), typeof(object));
//Goal 1: var selectExpression = Expression.Lambda<Func<objectType, object>>(expression, param);
var selectExpression = typeof(Expression).GetMethods().First(m => m.Name == "Lambda" && m.IsGenericMethod)
.MakeGenericMethod(typeof(Func<,>)
.MakeGenericType(objectType, typeof(object)))
.Invoke((object)null, new object[] { expression, new [] { param }});
// Goal 2: List<object> list = GetRepository(objectType).FindAllQuery().Select(x => x.SomeProperty).ToList();
List<object> list = GetRepository(objectType).FindAll().Select(selectExpression);
}
但知道我在目标 2 处得到了这个异常(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException):
'System.Collections.Generic.List' 不包含 “选择”的定义
这部分是正确的,因为它是在 System.Linq 中定义的,并且它是一种扩展方法。我如何让它工作?
【问题讨论】:
标签: c# .net reflection lambda expression-trees