我正在嘗試從一個常量字串陣列和一個引數創建一個 ExpressionTree。
var keys = "car,train".Split(','); // "car, train" will be given as a constant.
//var myModel = "MyModel-car"; // this will be given as a parameter
myModel => keys.Any(k => myModel.Contains(k)); // how to create this ExpressionTree?
我已經通讀了這個,但我的情況不同,因為委托 ( k => myModel.Contains(k)) 實際上有兩個引數。在這里,k由keys哪個是運行時的 ConstantExpression 決定。但在 Expression 主體中,它仍然是一個 ParameterExpression 實體。
我試過像:
var modelParam = Expression.Parameter(typeof(string)); // Example value: "MyModel-car".
var keys = "car,train".Split(',').AsQueryable().Expression;
var anyMethod = typeof(Enumerable).GetMethods()
.First(x => x.Name == "Any" && x.GetParameters().Length == 1)
.MakeGenericMethod(typeof(string));
var containsMethod = typeof(String).GetMethods()
.Where(x => x.Name == "Contains" && x.GetParameters().Length == 1)
.First(x => x.GetParameters().First().ParameterType == typeof(string));
var key = Expression.Parameter(typeof(string));
var containsCallExpr = Expression.Call(modelParam, containsMethod, key);
var lambda = Expression.Lambda(containsCallExpr, key);
Expression anyCallExpr = Expression.Call(keys, anyMethod, lambda); // throw an exception
Expression expr = Expression.Lambda(anyCallExpr, modelParam);
但是,該anycallExpr行引發例外:
靜態方法需要空實體,非靜態方法需要非空實體
有誰知道如何使這項作業?
[更新]
根據@Svyatoslav Danyliv 的建議,我更改了引數的順序,但顯示了不同的例外:
Incorrect number of arguments supplied for call to method 'Boolean Any[String](System.Collections.Generic.IEnumerable1[System.String])' (Parameter 'method')`
- 我認為這個例外是有道理的,因為我實際上有兩個引數。
uj5u.com熱心網友回復:
嘗試以下實作:
var modelParam = Expression.Parameter(typeof(string), "model") ; // Example value: "MyModel-car".
var keys = "car,train".Split(',').AsEnumerable();
var keysExpression = Expression.Constant(keys);
var containsMethod = typeof(string).GetMethods()
.Where(x => x.Name == nameof(string.Contains) && x.GetParameters().Length == 1)
.First(x => x.GetParameters().First().ParameterType == typeof(string));
var key = Expression.Parameter(typeof(string), "k");
var containsCallExpr = Expression.Call(modelParam, containsMethod, key);
var lambda = Expression.Lambda(containsCallExpr, key);
Expression anyCallExpr = Expression.Call(typeof(Enumerable), nameof(Enumerable.Any),
new[] { typeof(string) }, keysExpression, lambda);
Expression expr = Expression.Lambda(anyCallExpr, modelParam);
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/494227.html
