C#在运行时使用字符串创建表达式
那么让我们假设我有以下方式的方法:C#在运行时使用字符串创建表达式,c#,linq,runtime,expression,C#,Linq,Runtime,Expression,那么让我们假设我有以下方式的方法: public T Get<T, U>(Expression<Func<T, U>> expr) { // use the expression to retrieve cool stuff. } 然后有另一个类栏: public class Bar { public string AnotherName { get; set; } } 现在我想编译一个如下所示的表达式: Foo foo = new Foo
public T Get<T, U>(Expression<Func<T, U>> expr) {
// use the expression to retrieve cool stuff.
}
然后有另一个类栏:
public class Bar {
public string AnotherName { get; set; }
}
现在我想编译一个如下所示的表达式:
Foo foo = new Foo { Name = "AName" };
Expression<Func<Bar, string>> expr = p => p.AnotherName == foo.Name;
例如:
var sourceValue = "AName";
var targetClassName = "Bar";
var targetPropertyName = "AnotherName";
var expr = string.Format("{0}.{1} == {2}",
targetClassName, targetPropertyName, sourceValue);
var p = Expression.Parameter(typeof(Bar), "Target");
var e = System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { p }, null, expr);
var lambda = e.Compile();
但是,这只会导致对lambda表达式的委托
我现在的问题是,是否可以通过在运行时创建这样的表达式来调用Get方法?我认为您不需要动态:
var sourceValue = "AName";
// You will need the namespace of Bar here!
var namespaceTargetClassName = "ExpressionProblem";
var targetClassName = "Bar";
var targetPropertyName = "AnotherName";
{
var targetType = Type.GetType(namespaceTargetClassName + "." + targetClassName);
var p = Expression.Parameter(targetType, "Target");
var pr = Expression.PropertyOrField(p, targetPropertyName);
var e = Expression.Equal(pr, Expression.Constant(sourceValue));
var lambda = Expression.Lambda(e, p); // It would be an Expression<Func<Bar, bool>>
}
var sourceValue=“AName”;
//您需要在这里使用Bar的名称空间!
var namespaceTargetClassName=“ExpressionProblem”;
var targetClassName=“Bar”;
var targetPropertyName=“其他名称”;
{
var targetType=Type.GetType(namespaceTargetClassName+“+”+targetClassName);
var p=表达式参数(targetType,“Target”);
var pr=Expression.PropertyOrField(p,targetPropertyName);
var e=表达式.Equal(pr,表达式.Constant(sourceValue));
var lambda=Expression.lambda(e,p);//它将是一个表达式
}
请注意,第一种解决方案有一个问题:您生成的委托类型是Func
,因此您无法轻松编译和使用它
创建内部执行强制转换的Func
更容易
{
var targetType = Type.GetType(namespaceTargetClassName + "." + targetClassName);
var p = Expression.Parameter(typeof(object), "Target");
// I'm using the as operator here, if you prefer a "strong"
// cast (the cast operator that throws if the object is of
// invalid type), use Expression.Convert with the same syntax
var pcasted = Expression.TypeAs(p, targetType);
var pr = Expression.PropertyOrField(pcasted, targetPropertyName);
var e = Expression.Equal(pr, Expression.Constant(sourceValue));
var lambda = Expression.Lambda<Func<object, bool>>(e, p);
Func<object, bool> func = lambda.Compile();
Bar obj = new Bar { AnotherName = "AName" };
bool res = func(obj);
}
{
var targetType=Type.GetType(namespaceTargetClassName+“+”+targetClassName);
var p=表达式参数(typeof(object),“Target”);
//我在这里使用as运算符,如果你喜欢“强”
//cast(如果对象是
//无效类型),请使用表达式。使用相同语法进行转换
var pcasted=Expression.TypeAs(p,targetType);
var pr=Expression.PropertyOrField(pcasted,targetPropertyName);
var e=表达式.Equal(pr,表达式.Constant(sourceValue));
var lambda=表达式lambda(e,p);
Func Func=lambda.Compile();
Bar obj=新的Bar{AnotherName=“AName”};
bool res=func(obj);
}
搜索CSharpCodeProvider
。也许杀伤力过大,但它会解决你的问题。
var sourceValue = "AName";
// You will need the namespace of Bar here!
var namespaceTargetClassName = "ExpressionProblem";
var targetClassName = "Bar";
var targetPropertyName = "AnotherName";
{
var targetType = Type.GetType(namespaceTargetClassName + "." + targetClassName);
var p = Expression.Parameter(targetType, "Target");
var pr = Expression.PropertyOrField(p, targetPropertyName);
var e = Expression.Equal(pr, Expression.Constant(sourceValue));
var lambda = Expression.Lambda(e, p); // It would be an Expression<Func<Bar, bool>>
}
{
var targetType = Type.GetType(namespaceTargetClassName + "." + targetClassName);
var p = Expression.Parameter(typeof(object), "Target");
// I'm using the as operator here, if you prefer a "strong"
// cast (the cast operator that throws if the object is of
// invalid type), use Expression.Convert with the same syntax
var pcasted = Expression.TypeAs(p, targetType);
var pr = Expression.PropertyOrField(pcasted, targetPropertyName);
var e = Expression.Equal(pr, Expression.Constant(sourceValue));
var lambda = Expression.Lambda<Func<object, bool>>(e, p);
Func<object, bool> func = lambda.Compile();
Bar obj = new Bar { AnotherName = "AName" };
bool res = func(obj);
}