问题
I'm currently working on a project at work, and we are using the Telerik RadControls for Silverlight. In their Q1 2011 release, they added a new control called the Rad Expression Editor. In the Rad Expression Editor, you can pass in an object and create formulas (or expressions), and the editor window will give you a preview of the result of the expression. I've spoken with Telerik about this and they intentionally did not expose the result of this, but mentioned that I could use LambdaExpression.Compile(). I'm very new to Linq and using Lambda Expressions in general, but started looking into this.
As an example, lets say I have an object called Finances, and in that object, there are 4 nullable decimal fields (values): Debit (10), DebitYTD (100), Credit (20) and CreditYTD (200). In the formula, I want to do something like: Debit - Credit + DebitYTD - CreditYTD.
The Telerik Rad Expression Editor will give me the expression that is generated:
ExpressionEditor.Expression = {Param_0 => ((Param_0.Debit - Param_0.Credit + Param_0.DebitYTD - Param_0.CreditYTD}
The result of this expression should be -110. I need to be able to get the value that is calculate in the expression, but have not been able to figure out how to get this number. Can anyone please explain how this can be accomplished? Thanks.
回答1:
You haven't really told us much about the API which it exposes, but it sounds like you could use:
var compiled = ExpressionEditor.Expression.Compile();
var result = compiled(input);
where input
is an appropriate variable of type Finances
.
EDIT: Okay, as the expression isn't exposed nicely:
var typeSafe = (Expression<Func<Finance, decimal?>>) ExpressionEditor.Expression;
var compiled = typeSafe.Compile();
var result = compiled(input);
回答2:
I had very similar requirements. There was a need to compile expression and evaluate at runtime against different instances. However function compilation is not so trivial as you have to know the type of the result value during compile time and in most of the cases this will be impossible: user writes "1+1" and you get System.Int32, or user writes "(1+1).ToString()" and you get System.String. I'm sure this is the point where you experience (or will experience) difficulties.
In order to solve the expression compilation problem I would recommend jumping into DLR (Dynamic Language Runtime). You will need to reference "Microsoft.CSharp" assembly for your Silverlight project. As you need just access to "Compile" method for the expression (that is already in there), it will be fair enough doing that against "dynamic" object. Here's a short sample to demonstrate that:
dynamic dynamicExpression = expressionEditor.Expression;
dynamic compiledExpression = dynamicExpression.Compile();
object executionResult = compiledExpression(myInstance);
The "executionResult" variable will hold the result of expression evaluation. Now you can do whatever you need to do with the result.
Hope that helps
来源:https://stackoverflow.com/questions/5858886/how-to-get-a-calculated-value-from-a-compiled-lambdaexpression