Marc Gravell中post的答案解释了如何创建表达式:
var lambda = CreateExpression<SomeModel, bool>("IsAlive");
可以避免使用显式类型bool,并且该方法从&#34; IsAlive&#34;中获取返回类型。属性?
这样的事情:
var lambda = CreateExpression<SomeModel>("IsAlive");
而lambda将是Expression<Func<SomeModel, bool>>
。
并在:
var lambda = CreateExpression<SomeModel>("StringProperty");
lambda将是Expression<Func<SomeModel, string>>
。
答案 0 :(得分:1)
您可以实际上这样做,但类型变得未知。从此方法返回的对象将具有正确的类型Expression<Func<Test, string>>
,但在编译时不能强类型:
static LambdaExpression CreateExpression<TModel>(string propertyName)
{
var t = typeof(TModel);
var param = Expression.Parameter(typeof(TModel), "x");
//get the type for the 2nd generic arg
var propType = t.GetProperty(propertyName).PropertyType;
//make the generic type Func<TModel, TProp>
Type genericFuncType = typeof(Func<,>).MakeGenericType(new Type[] { typeof(TModel), propType });
//get the Expression.Lambda method
MethodInfo mi = typeof(Expression).GetMethods().First(a => a.Name == "Lambda" && a.GetParameters().Length == 2);
//get the Expression.Lambda<Func<TModel, TProp>> method
MethodInfo mi2 = mi.MakeGenericMethod(new Type[] { genericFuncType });
//Call Expression.Lambda<Func<TModel, TProp>>
return (LambdaExpression)mi2.Invoke(null, new object[] { Expression.PropertyOrField(param, propertyName), new ParameterExpression[] { param }});
}
但请注意,返回类型现在有些未知,需要使用强制转换(或使用动态)。
所以现在你需要更多的代码来投射它。也许这在某种工厂或类似工具中很有用 - 不确定你的用例。
class Program
{
public static void Main(string[] args)
{
var theExpression = CreateExpression<Test>("Name");
var theExpressionStrongType = theExpression as Expression<Func<Test, string>>;
//now you could use theExpressionStrongType
//or do this and go wild. :)
dynamic d = theExpression;
Console.ReadKey();
}
}
class Test
{
public string Name { get; set; }
}
免责声明:如果您真的想在生产环境中使用它,我会清理代码以获得一次反复类型等等......