Git Product home page Git Product logo

lambdaparser's Introduction

NReco LambdaParser

Runtime parser for string expressions (formulas, method calls, properties/fields/arrays accessors). LambdaParser builds dynamic LINQ expression tree and compiles it to the lambda delegate. Types are resolved at run-time like in dynamic languages.

NuGet Windows x64 Linux
NuGet Release AppVeyor Tests
  • can be used in any .NET app: net45 (legacy .NET Framework apps), netstandard1.3 (.NET Core apps), netstandard2.0 (all modern .NET apps).
  • any number of expression arguments (values can be provided as dictionary or by callback delegate)
  • supports arithmetic operations (+, -, *, /, %), comparisons (==, !=, >, <, >=, <=), conditionals including (ternary) operator ( boolVal ? whenTrue : whenFalse )
  • access object properties, call methods and indexers, invoke delegates
  • dynamic typed variables: performs automatic type conversions to match method signature or arithmetic operations
  • create arrays and dictionaries with simplified syntax: new dictionary{ {"a", 1}, {"b", 2} } , new []{ 1, 2, 3}
  • local variables that may go before main expression: var a = 5; var b = contextVar/total*100; (disabled by default, to enable use LambdaParser.AllowVars property)

Nuget package: NReco.LambdaParser

var lambdaParser = new NReco.Linq.LambdaParser();

var varContext = new Dictionary<string,object>();
varContext["pi"] = 3.14M;
varContext["one"] = 1M;
varContext["two"] = 2M;
varContext["test"] = "test";
Console.WriteLine( lambdaParser.Eval("pi>one && 0<one ? (1+8)/3+1*two : 0", varContext) ); // --> 5
Console.WriteLine( lambdaParser.Eval("test.ToUpper()", varContext) ); // --> TEST

(see unit tests for more expression examples)

Custom values comparison

By default LambdaParser uses ValueComparer for values comparison. You can provide your own implementation or configure its option to get desired behaviour:

  • ValueComparer.NullComparison determines how comparison with null is handled. 2 options:
    • MinValue: null is treated as minimal possible value for any type - like .NET IComparer
    • Sql: null is not comparable with any type, including another null - like in SQL
  • ValueComparer.SuppressErrors allows to avoid convert exception. If error appears during comparison exception is not thrown and this means that values are not comparable (= any condition leads to false).
var valComparer = new ValueComparer() { NullComparison = ValueComparer.NullComparisonMode.Sql };
var lambdaParser = new LambdaParser(valComparer); 

Who is using this?

NReco.LambdaParser is in production use at SeekTable.com and PivotData microservice (used for user-defined calculated cube members: formulas, custom formatting).

License

Copyright 2016-2024 Vitaliy Fedorchenko and contributors

Distributed under the MIT license

lambdaparser's People

Contributors

microspud avatar rducom avatar some1one avatar vitaliymf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lambdaparser's Issues

nested expression in dictionary indexer

this is working pretty fine:
new dictionary {{0,0}, {1,1}, {3,2}} [3]

this is throwing exception:
new dictionary {{0,0}, {1,1}, {3,2}} [x.Sum()]

System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
----> System.Exception : The given key was not present in the dictionary.

x is instance of class with object Sum() method, that returns 1

Help with .NET Standard

I am upgrading my nugets to .NET Standard, and while upgrading NReco.LambdaParser in my .NET 4.6.1 projects, I get the following error:

Failed to add reference. The package 'NReco.LambdaParser' tried to add a framework reference to 'System.Collections' which was not found in the GAC. This is possibly a bug in the package. Please contact the package owners for assistance.

Is this a known issue, by chance?

How to throw exception?

       var valComparer = new ValueComparer() { NullComparison = ValueComparer.NullComparisonMode.Sql };
       var lambdaParser = new NReco.Linq.LambdaParser(valComparer);
       var varContext = new Dictionary<string, object>();
       varContext["pi"] = 3.14M;
       var res=  lambdaParser.Eval("pi>what", varContext); 

I don't have a variable name called what,So I hope I can catch an exception and give me some hints for checking,Instead of directly returning a false to me,How to catch an exception? or tell me variable name error?

System.PlatformNotSupportedException: Operation is not supported on this platform.

We are getting this Exception on iOs. On Android it works perfectly.

System.PlatformNotSupportedException: Operation is not supported on this platform.
at System.Linq.Expressions.Compiler.DelegateHelpers.MakeNewDelegate (System.Type[] types) <0x102e341e0 + 0x000cc> in <bb5b9967994b42d38a9a568699a96020#cbe1a7eadba32ea3a937327d324ab3f9>:0
at System.Linq.Expressions.Compiler.DelegateHelpers.MakeDelegateType (System.Type[] types) <0x102e33990 + 0x00133> in <bb5b9967994b42d38a9a568699a96020#cbe1a7eadba32ea3a937327d324ab3f9>:0
at System.Linq.Expressions.Expression.Lambda (System.Linq.Expressions.Expression body, System.String name, System.Boolean tailCall, System.Collections.Generic.IEnumerable1[T] parameters) <0x102dcea00 + 0x001bf> in <bb5b9967994b42d38a9a568699a96020#cbe1a7eadba32ea3a937327d324ab3f9>:0 at System.Linq.Expressions.Expression.Lambda (System.Linq.Expressions.Expression body, System.Boolean tailCall, System.Collections.Generic.IEnumerable1[T] parameters) <0x102dce980 + 0x00027> in <bb5b9967994b42d38a9a568699a96020#cbe1a7eadba32ea3a937327d324ab3f9>:0
at System.Linq.Expressions.Expression.Lambda (System.Linq.Expressions.Expression body, System.Linq.Expressions.ParameterExpression[] parameters) <0x102dce950 + 0x0001f> in <bb5b9967994b42d38a9a568699a96020#cbe1a7eadba32ea3a937327d324ab3f9>:0
at NReco.Linq.LambdaParser.Eval (System.String expr, System.Func2[T,TResult] getVarValue) <0x103f20090 + 0x0016b> in <ebdc87cda8e4462a9cdd9c66afdb543c#cbe1a7eadba32ea3a937327d324ab3f9>:0 at NReco.Linq.LambdaParser.Eval (System.String expr, System.Collections.Generic.IDictionary2[TKey,TValue] vars) <0x103f1ff50 + 0x00113> in <ebdc87cda8e4462a9cdd9c66afdb543c#cbe1a7eadba32ea3a937327d324ab3f9>:0
at CPM.Arda.Mobile.Questionnaire.Logic+<>c__DisplayClass0_0`1+<b__0>d[T].MoveNext () <0x103f19220 + 0x0025f> in <3200b1f0bb96405aa11baec7b62f15e6#cbe1a7eadba32ea3a937327d324ab3f9>:0
ExpressionGroudId: 7e7207be-fd8c-40e1-9b90-0ca5bad1a5ec
EvalString: (val1.Contains(val2) || val3.Contains(val4) || val5.Contains(val6) || val7.Contains(val8) || val9.Contains(val10) || val11.Contains(val12) || val13.Contains(val14) || val15.Contains(val16) || val17.Contains(val18) || val19.Contains(val20))
EvalArguments: [val17, ][val16, 8][val5, ][val15, ][val1, ][val14, 7][val13, ][val9, ][val12, 6][val11, ][val10, 5][val4, 2][val8, 4][val7, ][val3, ][val6, 3][val2, 1][val19, ][val20, 10;][val18, 9]

This is the expression string:

(val1.Contains(val2) || val3.Contains(val4) || val5.Contains(val6) || val7.Contains(val8) || val9.Contains(val10) || val11.Contains(val12) || val13.Contains(val14) || val15.Contains(val16) || val17.Contains(val18) || val19.Contains(val20))

And the values:

[val20, 10;]
[val17, 2;4;5;7;8;]
[val12, 6]
[val7, 2;4;5;7;8;]
[val2, 1]
[val19, 2;4;5;7;8;]
[val13, 2;4;5;7;8;]
[val8, 4]
[val3, 2;4;5;7;8;]
[val1, 2;4;5;7;8;]
[val5, 2;4;5;7;8;]
[val16, 8]
[val18, 9]
[val14, 7]
[val4, 2]
[val11, 2;4;5;7;8;]
[val9, 2;4;5;7;8;]
[val10, 5]
[val15, 2;4;5;7;8;]
[val6, 3]

Allow recursivity

I just discovred your library and its awesome.
I am just wondering if it would be possible to do this kind of operations :
NOT(NOT(true))
or
NOT(1==1)
I tried it and obtained this exception :
System.InvalidOperationException: 'An expression of type 'System.Boolean' cannot be used to initialize an array of type 'System.Object''

The idea behind those simple exemples is to allow the possibility to chain operations.

Regards,

Eric

Improve performance by compiling into lambda method calls, property getters etc

Right now all invocations are performed through reflection (InvokeMethod / InvokeDelegate / InvokeIndexer / InvokePropertyOrField). At the same time, evaluation performance is acceptable for most applications: 10,000 evals take about 20-30ms (depending on CPU).

It is possible to improve evaluation performance in cases if invocation is not ambiguous (only one method overload is available according to number of parameters); this might be useful if LambdaParser is used for in-memory filtering of large dataset (say, >100k rows) by user-defined expression.

If someone needs this improvement please leave a comment or vote for this issue.

Error - Filter Datatable with LINQ inside the .Eval function

Hi,

after a lot of searching I came across this package which seemed perfect for what I needed.

I'm basically trying to filter a DataTable with a LINQ query that's been generated in runtime.

Imagine I have the DataTable dtToFilter, I'd do something like this: (From row In dtToFilter.AsEnumerable Where row("Name").ToString.StartsWith("A") OR row("Name").ToString.StartsWith("B") AND row("Age").ToString = "18" AND row("Occupation").ToString.Contains("rpa") Select row).CopyToDataTable

In my case, the above code is generated an therefore available in a string variable (filterString). My idea was to use your package like this:

Dim lambdaParser As NReco.Linq.LambdaParser = New NReco.Linq.LambdaParser()
Dim context As New Dictionary(Of String, Object)
context.Add("dtToFilter", dtToFilter)
output = lambdaParser.Eval(filterString, context)

Unfortunately it throws the following error:

 NReco.Linq.LambdaParserException: Expected ')' at 5: (From row In dtToFilter.AsEnumerable Where row("Name").ToString.StartsWith("A") OR row("Name").ToString.StartsWith("B") AND row("Age").ToString = "18" AND row("Occupation").ToString.Contains("rpa") Select row).CopyToDataTable 
   at NReco.Linq.LambdaParser.ParseValue(String expr, Int32 start)
   at NReco.Linq.LambdaParser.ParsePrimary(String expr, Int32 start)
   at NReco.Linq.LambdaParser.ParseUnary(String expr, Int32 start)
   at NReco.Linq.LambdaParser.ParseMultiplicative(String expr, Int32 start)
   at NReco.Linq.LambdaParser.ParseAdditive(String expr, Int32 start)
   at NReco.Linq.LambdaParser.ParseEq(String expr, Int32 start)
   at NReco.Linq.LambdaParser.ParseAnd(String expr, Int32 start)
   at NReco.Linq.LambdaParser.ParseOr(String expr, Int32 start)
   at NReco.Linq.LambdaParser.ParseConditional(String expr, Int32 start)
   at NReco.Linq.LambdaParser.Parse(String expr)
   at NReco.Linq.LambdaParser.Eval(String expr, Func`2 getVarValue)
   at NReco.Linq.LambdaParser.Eval(String expr, IDictionary`2 vars)
   at UiPathCodeRunner_3e7f94b226e64e9ab40aa7833cf4c058.Run(String filterString, DataTable dtToFilter, Object& output)

Do you have any tips on how to solve this or is this not possible?

Edit: Here's a simple fiddle: https://dotnetfiddle.net/uK5Mbe

escaping quotes in nested strings

parsing fails with string in expression

test string:

var exp = "true ? \"<br><br><span style=\\\"color:red;\\\">hello</span> world\" : \"\""
            
var result = SUT.Eval(exp, new Dictionary<string, object>());

fails with

NReco.Linq.LambdaParserException : Expected ':' at 30: true ? "<br><br><span style=\"color:red;\">hello</span> world" : ""
   at NReco.Linq.LambdaParser.ParseConditional(String expr, Int32 start)
   at NReco.Linq.LambdaParser.Parse(String expr)
   at NReco.Linq.LambdaParser.Eval(String expr, Func`2 getVarValue)
   at NReco.Linq.LambdaParser.Eval(String expr, IDictionary`2 vars)

it is not support Convert

var res = lambdaParser.Eval("Convert.ToInt32("111")", varContext)

this is not work well. how to support more system namespace class and functions?

null in expression evaluated as variable

Hi,

first of all thank you for you project. It is helping a lot in a project I am working on.

There is an issue when I use null to evaluate a boolean expression, for example:

20 == null

In this case, null is considered a variable and it is expected on the values dictionary.

The workaround I am using is:
values["null"] = null;

Thanks again and regards,

Lambda Sum or Select

Hey guys, I'm trying to perform the expression below like Sum(x=>x.UnitQuantity) or Select(x=>x...) but I'm unable to parse it properly and I am getting this exception error below. Am I missing something with my expression?

NReco.Linq.LambdaParserException: 'Expected value at 22: order.OrderLines.Sum(d => d.UnitPrice * d.UnitQuantity)'

`

       var lambdaParser = new LambdaParser();
        var order = new Order()
        {
            Id = 1,
            Paid = true,
            OrderReference = "Animal",
            OrderLines = new List<OrderLine>
                {
                    new OrderLine
                    {
                        Id = 1,
                        UnitQuantity = 3,
                        Category = "CAT",
                        UnitPrice = 1.1M
                    },
                    new OrderLine
                    {
                        Id = 2,
                        UnitQuantity = 7,
                        Category = "DOG",
                        UnitPrice = 3.1M
                    }
                }
        };

        var context = new Dictionary<string, object>
        {
            ["order"] = order
        };

        //var expression = "order.Paid ? order.OrderLines.Sum(d=>d.UnitPrice * d.UnitQuantity) : order.OrderLines.Sum(d=>d.UnitPrice * d.UnitQuantity) * 2.0M";
					
  var expression = "order.OrderLines.Sum(d => d.UnitPrice * d.UnitQuantity)";
       var result = lambdaParser.Eval(expr, context);

`

"Expected value" error in simple expression

Hello,

I have been trying to figure out why a more complex expression using vars was failing, but after working it down to a simple example, I still get an unexpected failure:

var result = parser.Eval("200 / 150 >= .75", vars);
Expected value at 12: 200 / 150 >= .75

I have tried using parentheses also, to no avail. It looks from the unit tests that all of the basic operators and such that I'm using are supported (even in the more complex example), so I'm scratching my head hoping it's not something so blindingly obvious that I'm going to feel like an idiot :)

I have used this parser for more complex expressions with no issue, and the only difference in this case that I can discern is that this is a nested operation (whereby 200 / 150 needs to be evaluated, and then the result used for the comparison). But, some of the unit tests seem to indicate this is possible, for example:

Assert.Equal(true, lambdaParser.Eval(" (1+testObj.IntProp)==2 ? testObj.FldTrue : false ", varContext));

So, I'm at a loss! What have I missed?

Variables in expressions

Motivation: in complex expressions where the same calculation result may be used more than once it expression may become monstrous because of copy-pastes of the same sub-expression, and also this causes multiple evaluations of the same value.

To prevent that let's add support of local variables that may be defined in that way:

var a = 5; var b = fromContext*2;  b>a ? b : a 

To keep full backward compatibility variables syntax should be controlled via LambdaParser.AllowVars property (false by default).

Linq Functions Suppport

Expression of "values.Count" is working.
But values.Max or values.Min is not working...
can you fix it?

Parser Context Security

Not an issue but a question - company I work for is interested in using the library but wants to know what security constraints are imposed within the parser context.
Specifically things that help avoid equivalent of sql injection attacks.

Custom values comparer

Current comparison logic handles nulls in the following way:

  • if a=null then "a==null" return true
  • if a not null then "a>null" returns true

In some cases SQL-like behavior is desired when any comparison with null returns false.
For this purpose

  • lets enhance API to add ability to specify custom comparer
  • add "NullBehaviour" property to ValueComparer implementation. By default current logic is preserved ("MinValue") and lets add "Sql" option that returns false if any operand is null.

function call evaluation fails for parameters that don't implement IConvertible

Hi, found a problem when evaluating a function call on an externally supplied function - it only works for parameters that implement IConvertible. Simple value types have it but custom classes don't - then the eval fails with InvalidCastException. Test code provided below, stack trace too for the failing case.

What is interesting - when I implement the IConvertible interface it works OK without calling any methods from IConvertible - so it looks like runtime doesn't use it at all, it's required just to be there. But unfortunately i dont have the option to implement IConvertible on all objects passed to evaluator. Can you please verify this and provide some fix? Unfortunately, i'm not able to do the VS builds myself for all .Net versions.

(edit) this is probably caused by always calling Convert.ChangeType on method params in LambdaParameterWrapper which always requires IConvertible. Instead, it should cast if possible, and only do Convert.ChangeType when casting wouldn't work.

Thanks
RG

Test Name:	NReco_TestFunctionCall
Test FullName:	Test1.EvalTests.NReco_TestFunctionCall
Test Source:	D:\rafal\facile\FacileWeb\Test1\EvalTests.cs : line 357
Test Outcome:	Failed
Test Duration:	0:00:29.5014222

Result StackTrace:	
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
   at NReco.Linq.LambdaParameterWrapper.InvokeDelegate(Object obj, Object[] args)
   at lambda_method(Closure , LambdaParameterWrapper , LambdaParameterWrapper )
 --- End of inner exception stack trace ---
    at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Delegate.DynamicInvokeImpl(Object[] args)
   at NReco.Linq.LambdaParser.Eval(String expr, Func`2 getVarValue)
   at NReco.Linq.LambdaParser.Eval(String expr, IDictionary`2 vars)
   at Test1.EvalTests.NReco_TestFunctionCall() in D:\rafal\facile\FacileWeb\Test1\EvalTests.cs:line 371
Result Message:	
Test method Test1.EvalTests.NReco_TestFunctionCall threw exception: 
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidCastException: Object must implement IConvertible.
public class LambdaTestLine
        {
            public int Id { get; set; }
            public decimal Amount { get; set; }
            public string Label { get; set; }
        }

        [TestMethod]
        public void NReco_TestFunctionCall()
        {
            var p = new NReco.Linq.LambdaParser();

            var vars = new Dictionary<string, object>
            {
                {"funfun", (Func<object, string>) (x => "AAA" + x + "BBB") },
                {"someValue", "ding" },
                {"someObject", new LambdaTestLine { Id=150, Amount=22, Label = "xxxx" } }
            };

            var x0 = p.Eval("funfun(someValue)", vars);
            Assert.AreEqual("AAAdingBBB", x0);

            var x1 = p.Eval("funfun(someObject)", vars); //this explodes
            
        }

Expressions using "not" not always work

Hello

I´ve found that the parser raises an exception in cases like this:
not ( foo = bar)
anyway **not** works as expected in expressions like
((foo and foo1 = bar1 ) or not (foo2 = bar2))
by replacing **not** by ! you get the expression working always.

I think this could be maybe an edge case of the issue #30

Thanks for the good job.

Jose

Changing order of parameters in simple expression produces different evaluation result.

This evaluates to true: lambdaParser.Eval("true == 2", new Dictionary<string, object>())
This evaluates false: lambdaParser.Eval("2 == true", new Dictionary<string, object>())

In the first instance, LambdaParser will try to convert 2 to a bool, and the expression is reduced to true == true.
In the second instance true is converted to an int32, and the expression becomes 2 == 0.

The issue lies in the way LambdaParser attempts to compare the two parameters and the implementation of the Convert.ToBoolean and Convert.ToInt32 methods.

  • ToBoolean(int32) will return true if the value provided is anything but 0, otherwise false.
  • ToInt32(bool) will return 1 if the value provided is true, otherwise 0.

In other words, the methods are not inverse of each other.

I'm not saying this is a bug with LambdaParser but it is an implementation detail that is worth flagging so that people don't get caught out by it.

A different approach would be to allow the caller to specify whether they wish LambdaParser to attempt to convert parameter types. If the caller sets this to false, in the example above, bool and int32 are not comparable (without conversion) and the expression would always evaluate to false.

Non-convertible types support

Would it be possible to support operations with types that support these operations but are not IConvertible?

Example:

varContext["complexZero"] = new System.Numerics.Complex();
varContext["complexOne"] = new System.Numerics.Complex(1d, 1d);

lambdaParser.Eval("complexOne * complexZero", varContext)

SL5 MacOs support

I am using LambdaParser in a SL5 application, every thing is working correctly on Windows clients, but formulas are not evaluated on MacOs. The application is running with elevated privileges (signed and OOB).
Maybe need to reference some extra assemblies ?

Exception when checking for null and other bool condition

Hello,

when I try the following code

var value = "testString";
var env = new Dictionary<string, object>();
env.Add("value", value);
var parser = new LambdaParser();
string res = (string)parser.Eval("value != null && value.Contains(\"t\") ? \"contains\" : \"does not contain\"", env);

I get this exception: System.InvalidOperationException: "The binary operator AndAlso is not defined for the types 'System.Boolean' and 'NReco.Linq.LambdaParameterWrapper'."

There seems to be a problem combining a check for null with another condition. If I do only the null check there is no problem.

LambdaParser.Parse

We're exploring a possible use case here:
ExtendedXmlSerializer/home#382

And the thought arose to check out your parser, which has a Parse method. :)

However, I am having some trouble using it and feel I may be using it incorrectly. Unfortunately I do not see any tests around this method, so asking here.

Is it possible to use this method to parse the following into a expression (of Func<int>)?

"() => 123"

Thank you for any guidance you can provide. 👍

Failed DateTime.Now

I used the simple code but it resulted in a null reference exception. Is this supported?

var varContext = new Dictionary<string, object>();
var lambdaParser = new NReco.Linq.LambdaParser();
Console.WriteLine(lambdaParser.Eval("System.DateTime.Now", varContext));
Console.Read();

image

Support for dynamic types like expando object

I was testing Lambdaparser.eval() to handle user expression, where values are added to an expandoObject. This way I could create a dynamic object that contains properties which can be used in the expression. But it seems that expandoObjects and dynamic objects are not supported. Here is a snippet of my unit test with the ExpandoObject:

var lambdaParser = new LambdaParser();
var varContext = new Dictionary<string, object>(); 

dynamic dynamicDiplomas = new ExpandoObject();
dynamicDiplomas.ODB = true; /* this should come from a DB */
dynamicDiplomas.IDB = null;
varContext["diplomas"] = dynamicDiplomas;

expression = "diplomas.ODB || diplomas.IDB != null";

// MissingMemberException
Assert.Throws<System.Reflection.TargetInvocationException>(() => lambdaParser.Eval(expression, varContext));

Is this a known limitation?

Is it possible to build lambda for entity framework queries

I have a requirement to convert predicates issued as string to lambda used for EF queries. Is it possible with lambdaparser? Code snippet will be helpful. Thanks

Example:
using (var context = new EntityContext())
{
var customersList = context.Customers
.Where(c => "c.Invoices.Count > 2")
.ToList();
}

The problem of checking expression statements

When I wrote some code expressions, I wanted to check the syntax, such as whether the properties and methods were correct. I think using type reflection can check, but I wrote an incorrect property and did not prompt me for any errors. Why do I need this feature? Because I have defined some types of variables that may not have been assigned values, even though I have written code expressions, using Eval() function to check in real time will definitely result in errors. So, I wonder if you can implement pre checking for some code expressions, just to check if the syntax is correct. I think it should be possible in theory, but I don't know how to do it

var varContext = new Dictionary<string, object>();
varContext["dt"] = datatable;

Expression expr = lambdaParser.Parse("dt.Rows1[0]");
var exprParams = LambdaParser.GetExpressionParameters(expr);

dt is a System.DataTable type variable,Rows1 is an incorrect property,But it didn't give me any exceptions,i need some checks,how to do?

Security?

I can see from the examples that the expression can invoke native methods, like ToUpper. Is that safe to use when expressions are entered by a web application users?
Actually I'm looking for a simple math parser with conditional support ("if...else"), but all the solutions I found (yet) are using code generation in one way or another, which in my case is both overkill and security risk.

Sequence of ternary operators

Currently ternary operator requires extra brackets to get 'switch-like' evaluation flow, for example:

a<0 ? 0 : (a>100 ? 100 : -a)

In case when there are many 'elseif' this requires a lot of nested brackets. To avoid that it makes sense to allow next ternary operator for part (which is currently not allowed), this makes possible to use expressions like that:

v<0 ? "red"
: v<25 ? "white" 
: v<50 ? "lightgreen" 
: "green"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.