Tag: 表达式 树

使用属性的名称构建OrderBy表达式

我试图通过MVC3中的WebGrid控件来支持排序,MVC3通过sort参数将模型上的属性名称传递给我的操作。 public class Agent { public int Id { get; set; } public string Name { get; set; } } [HttpGet] public ActionResult Index(string sort = “Id”, string sortdir = “ASC”) { // Define the parameter that we are going to use in the OrderBy clause. var param = Expression.Parameter(typeof(Agent), “agent”); // Now we’ll make […]

如何使用表达式树调用带引用变量的方法

我试图弄清楚如何创建一个调用具有引用参数的方法的Expression。 让我用一个简单(但人为)的例子来解释我的问题。 考虑方法: public static int TwiceTheInput(int x) { return x*2; } 我可以通过执行以下操作来创建一个Expression来调用上面的方法: { var inputVar = Expression.Variable(typeof (int), “input”); var blockExp = Expression.Block( new[] {inputVar} , Expression.Assign(inputVar, Expression.Constant(10)) , Expression.Assign(inputVar, Expression.Call(GetType().GetMethod(“TwiceTheInput”, new[] { typeof(int) }), inputVar)) , inputVar ); var result = Expression.Lambda<Func>(blockExp).Compile()(); } 在执行时,上面的“结果”应该以20结尾。现在考虑使用by-reference参数的TwiceTheInput()版本: public static void TwiceTheInputByRef(ref int x) { x = […]

创建将一种类型的函数转换为另一种类型的函数

对于一些花哨的reflection内容,我有一个类型为Func的函数,需要将它传递给一个接受Func类型的函数,其中T在运行时才知道。 例如: public bool MyOperation(Func op) { return _myValues.Any(op); } public static bool InvokeOperationMethod(MethodInfo info, object obj,Func opAsObject) { info.Invoke(obj, opAsObject); } 问题在于,由于我有一个较弱类型的lambda,我不能将它作为更强类型的参数传递。 所以我尝试创建一个帮助程序,它将创建一个将较弱类型的lambda转换为更强类型的函数。 例如,我可以打电话 var converter = CreateConverter(typeof(string)); Func asObject = o => o.ToString() == “a string”; //Dump example Func asString = (Func)converter(asObject); Assert.IsTrue(asInt(“a string”)); 当然在实际代码中,目标类型直到运行时才知道,而实际谓词不是一些简单的测试。 这是我的尝试: /// /// Converts a predicate of Func […]

表达式树深度限制

我正面临一个问题,试图在Expression <Func >类型的LambdaExpression上调用Compile(),其深度大约为400.较小的值不会导致任何问题。 我找不到任何关于这种限制的事情。 任何人都可以澄清这个吗? 我可以增加这个限额吗? upd:对不起,忘了提,我得到了StackOverflowException: System.Core.dll中出现未处理的“System.StackOverflowException”类型exception{无法计算表达式,因为当前线程处于堆栈溢出状态。}

检测BinaryExpression中的括号

我正在构建一个表达式分析器,我想从中生成数据库查询代码,我已经走得很远,但是我很难准确地解析BinaryExpressions。 将它们分解为左和右很容易,但我需要检测括号并相应地生成我的代码,我看不到如何做到这一点。 一个例子[请忽略有缺陷的逻辑:)]: a => a.Line2 != “1” && (a.Line2 == “a” || a.Line2 != “b”) && !a.Line1.EndsWith(“a”) 我需要在中间检测’set’并保留它们的分组但是在解析期间我看不出表达式与正常BinaryExpression的任何差异(我不想检查括号的字符串表示) 任何帮助,将不胜感激。 (我应该提一下,我正在使用C#) – 编辑 – 我没有提到我使用标准的.Net Expression类来构建表达式(System.Linq.Expressions命名空间) –Edit2–好的我没有将文本解析为代码,我正在将代码解析为文本。 所以我的Parser类有这样的方法: void FilterWith(Expression<Func> filterExpression); 它允许你编写这样的代码: FilterWith(c => c.Name ==”asd” && c.Surname == “qwe”); 使用标准.Net类很容易解析,我的挑战是解析这个表达式: FilterWith(c => c.Name == “asd” && (c.Surname == “qwe” && c.Status == 1) && […]

表达/声明树

进一步更新问题 我一直在尝试使用.NET 4中的表达式树来在运行时生成代码,并且我一直在尝试通过构建表达式树来实现foreach语句。 最后,表达式应该能够生成执行此操作的委托: Action<IEnumerable> action = source => { var enumerator = source.GetEnumerator(); while(enumerator.MoveNext()) { var i = enumerator.Current; // the body of the foreach that I don’t currently have yet } } 我想出了以下帮助器方法,它从IEnumerable生成一个BlockExpression: public static BlockExpression ForEachExpr(this IEnumerable source, string collectionName, string itemName) { var item = Expression.Variable(typeof(T), itemName); var enumerator = Expression.Variable(typeof(IEnumerator), […]

“System.DateTime”类型的表达式不能用于返回类型“System.Object”

我创建了一个表达式,我正在使用它进行排序工作正常,直到我点击DateTime字段,我得到以下错误(在第二行): “System.DateTime”类型的表达式不能用于返回类型“System.Object” 这是我的代码: ParameterExpression param = Expression.Parameter(typeof(MyEntity), “x”); Expression<Func> sortExpression = Expression.Lambda<Func>( Expression.Property(param, sortKey), param); 任何人都可以帮忙吗?

从表达式树中提取方法名称?

我正在尝试实现以下模式函数: MethodInfo GetMethod( Expression<Func<TTarget, EventHandler>> method) 如果需要,我可以提供TTarget的实例 所需的用法是: public static void Main(string[] args) { var methodInfo = GetMethod(t => t.Method); Console.WriteLine(“Hello, world!”); } private void Method(object sender, EventArgs e) { } 这是我到目前为止所尝试的内容: private static MethodInfo GetMethod(TTarget target, Expression<Func<TTarget, EventHandler>> method) { var lambda = method as LambdaExpression; var body = lambda.Body as UnaryExpression; var call […]

获取表达式树中方法参数的值

我正在搞乱表达树,但我很难被卡住。 我有这个表达式: Expression<Func> expr = i => i.GetAll(1, b, method()); 地点: int b = 2; public static int method() { return 3; } public interface IX { int GetAll(int a, int b, int c); } 现在我想获得此方法的方法名称和参数值。 方法的名称很简单,但参数值更难。 我知道我可以自己解析它们,但我需要处理所有情况( ConstantExpression , MemberExpression , MethodCallExpression以及我可能不知道的更多)。 所以我在想是否有“一般”的方式来获得他们的价值观。 例如1,2,3。

表达树的表现

我目前的理解是这样的’硬编码’代码: public int Add(int x, int y) {return x + y;} 将始终比表达式树代码执行更好,如下所示: Expression<Func> add = (x, y) => x + y; var result = add.Compile()(2, 3); var x = Expression.Parameter(typeof(int)); var y = Expression.Parameter(typeof(int)); return (Expression.Lambda(Expression.Add(x, y), x, y). Compile() as Func)(2, 3); 因为编译器有更多的信息,如果你在编译时编译它,可以花更多的精力来优化代码。 这一般是正确的吗?