Closed Jiuyong closed 5 years ago
@Jiuyong as I remember we already discussed this in your PR (#11). If you need to traverse through Expression produced by LambdaParser and read constant values (they are wrapped with LambdaParameterWrapper
internal class) I proposed to add an interface - smth like ILambdaValue
- which can expose real "Value" object -- but I didn't get any confirmation that this is what you need.
Another alternative might be implementation of IConvertible for LambdaParameterWrapper class: in this case you'll able to check if Constant.Value is IConvertible, and if yes - use IConvertible.GetTypeCode and IConvertible.ToType to get real constant value.
As for me variant with IConvertible is more elegant.
Yes , I need to get the real "Value" from object .
@Jiuyong just let me know if my suggestions are correct and if they solve your problem I'll include these changes into next release.
Is it enough to implement IConvertible? Or you need ILambdaValue interface to determine contants in expressions produced by LambdaParser class?
by bing:
I mean, I need to get the value of the correct expression so that after I parse the expression with your component, I can implement the expression myself, rather than just using it to calculate the result.
So, if my translation doesn't make me ambiguous, your first implementation should be to meet my requirements.
Second, I want you to parse the string as the result of the functionality of the expression, preferably an API that maintains maximum consistency with direct code definitions or generated expressions. If this can be done, then interfaces such as the IQueryable
I parse the expression with your component, I can implement the expression myself, rather than just using it to calculate the result.
ok, let's assume that you already can handle values of ConstantExpression.
I want you to parse the string as the result of the functionality of the expression, preferably an API that maintains maximum consistency with direct code definitions or generated expressions.
LambdaParser was specially designed for 'dynamic typing' - when types are aligned in run-time, and this is main reason why all constants are wrapped with internal LambdaParameterWrapper class and InvokeMethod, InvokeDelegate, InvokePropertyOrField, InvokeIndexer method calls are used instead of direct calls of methods. This approach gives great flexibility when real types of variables (expression parameters) are unknown - this is typical case when these expressions are defined by end-user.
If you need a parser that produces expression tree that 1:1 reflects what you have in string expression NReco.LambdaParser is a not right choice; take a look to https://github.com/davideicardi/DynamicExpresso
If this can be done, then interfaces such as the IQueryable do not need to be handled separately, but are available for direct sharing.
Expression
produced by LambdaParser is NOT suitable for IQueryable (say, for usage as predicate in EntityFramework). You'll need to perform rather complicated 'reverse' translation to get rid of LambdaParameterWrapper, resolve real method calls instead of "InvokeMethod", "InvokeDelegate" and determine real types of variables (in other words, infer their types from context, which might be very nontrivial!) etc.
From what I see, you'll not able to use LambdaParser even if I'll add ability to access real value of ConstantExpression: resulting Expression is just not suitable for usage with IQueryable that are translated to DB queries.
Added ILambdaValue
interface that can be used for accessing real constant values in Expression
produced by LamdbaParser
.
Shipped in 1.0.9
i need it ...