[英]C# Creating an Expression in runtime with a string
所以,讓我說我有一種方法如下:
public T Get<T, U>(Expression<Func<T, U>> expr) {
// use the expression to retrieve cool stuff.
}
現在我想只使用字符串值調用此方法。 也就是說,我需要在運行時編譯表達式。
所以,讓我們說我有一個類Foo:
public class Foo {
public string Name { get; set; }
}
然后有另一個類Bar:
public class Bar {
public string AnotherName { get; set; }
}
現在我想編譯一個如下所示的表達式:
Foo foo = new Foo { Name = "AName" };
Expression<Func<Bar, string>> expr = p => p.AnotherName == foo.Name;
但是,我在運行時獲得的唯一信息是:
所以,在經歷了一些潛伏之后,我發現有一個System.Linq.Dynamic庫,我可以在其中編譯字符串的expr:
@"Bar.AnotherName == AName";
例:
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>>
}
請注意,第一個解決方案有一個問題:您生成的委托類型是Func<targetClassName, bool>
,因此您無法輕松編譯和使用它。
創建內部執行Func<object, bool>
轉換的Func<object, 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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.