Is there a parser for .NET expression trees?
-
If you already have code that parses C# expressions, why not use the factory methods at [`System.Linq.Expressions.Expression`](https://docs.microsoft.com/en-us/dotnet/api/system.linq.expressions.expression)?
That was my plan, but before I did it I wanted to see if it was done. My parser spits out CodeDOM constructs, so it needs some retooling to work with expressions.
Real programmers use butterflies
-
How about the Dynamic Linq library? GitHub - zzzprojects/System.Linq.Dynamic.Core: The .NET Standard / .NET Core version from the System Linq Dynamic functionality.[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
Are you looking for something like that?
var product = CSScript.CreateFunc(@"int Product(int a, int b)
{
return a * b;
}");
int result = product(3, 4);The solution (cs-script) is based on Roslyn engine.
-
@SanderRossel I believe you've used them before. Do you know anything that will let me do like Expression.Parse("1 + x"); or similar? Anyone? Bueller? Basically, I already have the code to parse C# expressions and turn them into trees. I'd simply have to modify it to make expression trees instead of codedom expression trees. The question is, am I reinventing the wheel?
Real programmers use butterflies
So not sure if this is what your looking for but I used the System.Linq.Expressions namespace to build a dynamic link query to be executed against EF. here is an incomplete sample for syntax example:
propertyToUse = workingProperty.Substring(0, workingProperty.IndexOf('.'));
Type propertyToUseType = GetEntityType(propertyToUse, incomingParentType);ParameterExpression propertyToUseParameterExpression = Expression.Parameter(propertyToUseType, propertyToUse.Substring(0,1)); Expression parentExpression = Expression.Property(workingExpression, propertyToUse); if (parentExpression.Type.IsGenericType && typeof(IEnumerable<>) .MakeGenericType(parentExpression.Type.GetGenericArguments()) .IsAssignableFrom(parentExpression.Type)) { Expression childExpression = BuildPropertyExpression(propertyToUseParameterExpression, workingProperty, comparisonOperation, compareValue); Type func = typeof(Func<,>); Type genericFunc = func.MakeGenericType(propertyToUseType, typeof(bool)); LambdaExpression predicate = Expression.Lambda(genericFunc, childExpression, propertyToUseParameterExpression); //we have call the AsQueryable on the collection since we don't have the compiler working for us and we need to use the any method MethodInfo asQueryableMethod = typeof(Queryable).GetMethods() .Where(m => m.Name == "AsQueryable") .Single(m => m.IsGenericMethod) .MakeGenericMethod(propertyToUseType); Expression asQueryableExpression = Expression.Call(null, asQueryableMethod, parentExpression); //call the any method with the lambda expression we set up MethodInfo anyMethod = typeof(Queryable).GetMethods() .Where(m => m.Name == "Any") .Single(m => m.GetParameters().Length == 2) .MakeGenericMethod(propertyToUseType); returnValue = Expression.Call( null, anyMethod, asQueryableExpression, //the source predicate); // the lambda expression }
There are other fa
-
CS0030 Cannot convert type 'string' to 'System.Linq.Expressions.Expression'
Yes. That was a joke, there's no way a string can simply be cast to an Expression ;)
Best, Sander sanderrossel.com Migrating Applications to the Cloud with Azure arrgh.js - Bringing LINQ to JavaScript Object-Oriented Programming in C# Succinctly
-
Sander Rossel wrote:
My coworker was like, "I could write a parser and spend a few days, or I can do it like this and be done with it
I can write an expression parser in about a day, but it would take forever to test
Sander Rossel wrote:
I did find some smart guy who just compiled a string using reflection (using ICodeCompiler.CompileAssemblyFromSource) and then simply invokes it
I actually considered that approach. Or using Roslyn. I think I'll avoid the Eval function, wherever it is. It probably compiles code anyway.
Real programmers use butterflies
honey the codewitch wrote:
but it would take forever to test
I wrote some TagHelpers for ASP.NET Core Razor and all your writing inspired me to write an article about it. So, clean up the code a bit (which took me hours, it was a mess, you'd be proud :laugh: ) and add unit tests... Turns out it's pretty much impossible to unit test those things! Here's the unit tests for the InputTagHelper: Mvc/InputTagHelperTest.cs at master · aspnet/Mvc · GitHub[^] That's almost 2000 lines and I inherited that thing :wtf: I'd need to test others too, like Mvc/SelectTagHelperTest.cs at master · aspnet/Mvc · GitHub[^] and Mvc/ValidationMessageTagHelperTest.cs at master · aspnet/Mvc · GitHub[^], another 1300 something LOC just for the basic tests :( But it doesn't stop there. It makes use of a "TestableHtmlGenerator", which I'm obviously going to need. Luckily, it's not a big class, but what the hell does it all do? :) Mvc/TestableHtmlGenerator.cs at master · aspnet/Mvc · GitHub[^] A single test would need about as much LOC as my entire library :sigh: So to hell with unit tests and back to some good old manual testing and praying for the best :laugh:
Best, Sander sanderrossel.com M
-
honey the codewitch wrote:
but it would take forever to test
I wrote some TagHelpers for ASP.NET Core Razor and all your writing inspired me to write an article about it. So, clean up the code a bit (which took me hours, it was a mess, you'd be proud :laugh: ) and add unit tests... Turns out it's pretty much impossible to unit test those things! Here's the unit tests for the InputTagHelper: Mvc/InputTagHelperTest.cs at master · aspnet/Mvc · GitHub[^] That's almost 2000 lines and I inherited that thing :wtf: I'd need to test others too, like Mvc/SelectTagHelperTest.cs at master · aspnet/Mvc · GitHub[^] and Mvc/ValidationMessageTagHelperTest.cs at master · aspnet/Mvc · GitHub[^], another 1300 something LOC just for the basic tests :( But it doesn't stop there. It makes use of a "TestableHtmlGenerator", which I'm obviously going to need. Luckily, it's not a big class, but what the hell does it all do? :) Mvc/TestableHtmlGenerator.cs at master · aspnet/Mvc · GitHub[^] A single test would need about as much LOC as my entire library :sigh: So to hell with unit tests and back to some good old manual testing and praying for the best :laugh:
Best, Sander sanderrossel.com M
Sander Rossel wrote:
So to hell with unit tests and back to some good old manual testing and praying for the best
That's the spirit! Liberating isn't it? What's a good program without a few bugs anyway? :-D
Real programmers use butterflies
-
Sander Rossel wrote:
So to hell with unit tests and back to some good old manual testing and praying for the best
That's the spirit! Liberating isn't it? What's a good program without a few bugs anyway? :-D
Real programmers use butterflies
honey the codewitch wrote:
What's a good program without a few bugs anyway?
A very short program :laugh:
Best, Sander sanderrossel.com Migrating Applications to the Cloud with Azure arrgh.js - Bringing LINQ to JavaScript Object-Oriented Programming in C# Succinctly
-
@SanderRossel I believe you've used them before. Do you know anything that will let me do like Expression.Parse("1 + x"); or similar? Anyone? Bueller? Basically, I already have the code to parse C# expressions and turn them into trees. I'd simply have to modify it to make expression trees instead of codedom expression trees. The question is, am I reinventing the wheel?
Real programmers use butterflies
I did it this way (and I an NOT a JavaScript programmer): 1. JavaScript code:
class JsMath
{
static function Eval(expression: String): double
{
return eval(expression);
};
}2. Compile:
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\jsc.exe /t:library jsMath.js
3. Use in C#:
private static double ExpressionValue(string expr) { return JsMath.Eval(expr); }
-
I did it this way (and I an NOT a JavaScript programmer): 1. JavaScript code:
class JsMath
{
static function Eval(expression: String): double
{
return eval(expression);
};
}2. Compile:
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\jsc.exe /t:library jsMath.js
3. Use in C#:
private static double ExpressionValue(string expr) { return JsMath.Eval(expr); }
well I suppose that's one way to do it. :-D
Real programmers use butterflies
-
well I suppose that's one way to do it. :-D
Real programmers use butterflies