{"id":24151342,"url":"https://github.com/xaviersolau/expressiontools","last_synced_at":"2026-04-04T12:57:49.447Z","repository":{"id":45248271,"uuid":"162638470","full_name":"xaviersolau/ExpressionTools","owner":"xaviersolau","description":"Tools allowing to parse textual C# Lambda Expression and more.","archived":false,"fork":false,"pushed_at":"2024-12-12T23:36:36.000Z","size":197,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-30T00:22:11.873Z","etag":null,"topics":["expression","lambda","lambda-expressions","netcore","netstandard","parse","parser","tools"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xaviersolau.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-12-20T22:37:54.000Z","updated_at":"2025-07-15T19:11:23.000Z","dependencies_parsed_at":"2025-01-12T09:15:18.732Z","dependency_job_id":"629c0870-d27d-49c3-beb8-a9748b5c23fd","html_url":"https://github.com/xaviersolau/ExpressionTools","commit_stats":{"total_commits":92,"total_committers":2,"mean_commits":46.0,"dds":0.06521739130434778,"last_synced_commit":"cc3ddfc6d55249b5cd3bd9f89dd472b795333756"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/xaviersolau/ExpressionTools","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xaviersolau%2FExpressionTools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xaviersolau%2FExpressionTools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xaviersolau%2FExpressionTools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xaviersolau%2FExpressionTools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xaviersolau","download_url":"https://codeload.github.com/xaviersolau/ExpressionTools/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xaviersolau%2FExpressionTools/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275982504,"owners_count":25564149,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-19T02:00:09.700Z","response_time":108,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["expression","lambda","lambda-expressions","netcore","netstandard","parse","parser","tools"],"created_at":"2025-01-12T09:15:14.076Z","updated_at":"2025-09-19T18:31:01.288Z","avatar_url":"https://github.com/xaviersolau.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ExpressionTools\r\n\r\nExpressionTools is a library that helps you to handle C# lambda expression.\r\nIt is written in C# and thanks to .Net Standard, it is cross platform.\r\n\r\nThe project is based on System.Linq.Expressions and uses the C# Roslyn compiler.\r\n\r\nDon't hesitate to post issues, pull requests on the project or to fork and improve the project.\r\n\r\n## Project dashboard\r\n\r\n[![Build - CI](https://github.com/xaviersolau/ExpressionTools/actions/workflows/build-ci.yml/badge.svg)](https://github.com/xaviersolau/ExpressionTools/actions/workflows/build-ci.yml)\r\n[![Coverage Status](https://coveralls.io/repos/github/xaviersolau/ExpressionTools/badge.svg?branch=master)](https://coveralls.io/github/xaviersolau/ExpressionTools?branch=master)\r\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\r\n\r\n| Package                                    | Nuget.org | Pre-release |\r\n|--------------------------------------------|-----------|-------------|\r\n|**SoloX.ExpressionTools.Parser**            |[![NuGet Beta](https://img.shields.io/nuget/v/SoloX.ExpressionTools.Parser.svg)](https://www.nuget.org/packages/SoloX.ExpressionTools.Parser)|[![NuGet Beta](https://img.shields.io/nuget/vpre/SoloX.ExpressionTools.Parser.svg)](https://www.nuget.org/packages/SoloX.ExpressionTools.Parser)|\r\n|**SoloX.ExpressionTools.Transform**         |[![NuGet Beta](https://img.shields.io/nuget/v/SoloX.ExpressionTools.Transform.svg)](https://www.nuget.org/packages/SoloX.ExpressionTools.Transform)|[![NuGet Beta](https://img.shields.io/nuget/vpre/SoloX.ExpressionTools.Transform.svg)](https://www.nuget.org/packages/SoloX.ExpressionTools.Transform)|\r\n\r\n\r\n## License and credits\r\n\r\nExpressionTools project is written by Xavier Solau. It's licensed under the MIT license.\r\n\r\n * * *\r\n\r\n## Installation\r\n\r\nYou can checkout this Github repository or you can use the NuGet package:\r\n\r\n**Install using the command line from the Package Manager:**\r\n```bash\r\nInstall-Package SoloX.ExpressionTools.Parser -version 1.0.5\r\nInstall-Package SoloX.ExpressionTools.Transform -version 1.0.5\r\n```\r\n\r\n**Install using the .Net CLI:**\r\n```bash\r\ndotnet add package SoloX.ExpressionTools.Parser --version 1.0.5\r\ndotnet add package SoloX.ExpressionTools.Transform --version 1.0.5\r\n```\r\n\r\n**Install editing your project file (csproj):**\r\n```xml\r\n\u003cPackageReference Include=\"SoloX.ExpressionTools.Parser\" Version=\"1.0.5\" /\u003e\r\n\u003cPackageReference Include=\"SoloX.ExpressionTools.Transform\" Version=\"1.0.5\" /\u003e\r\n```\r\n\r\n## How to use it\r\n\r\nNote that you can find code examples in this repository in this location: `src/examples`.\r\n\r\n### Parse a C# Lambda expression\r\n\r\n#### Simple\r\n\r\nA few lines of code are actually needed to parse a textual C# lambda expression.\r\nLet's say that we want to parse a simple lambda expression like `\"(int x) =\u003e x + 1\"` with x as an integer:\r\n\r\n```csharp\r\n// Set the expression to parse\r\nvar expToParse = \"(int x) =\u003e x + 1\";\r\n\r\n// We need to create the parser.\r\nvar expressionParser = new ExpressionParser();\r\n\r\n// We can just parse the expression.\r\nvar lambdaExpression = expressionParser.Parse(expToParse);\r\n\r\n// Or we can parse the expression specifying the type of the lambda expression.\r\nvar expression = expressionParser.Parse\u003cFunc\u003cint, int\u003e\u003e(expToParse);\r\n```\r\n\r\nThe Parse method will return an expression tree (from `System.Linq.Expressions`) reflecting the given textual\r\nC# lambda expression.\r\n\r\nMore precisely, The resulting expression object is based on `System.Linq.Expressions.LambdaExpression`.\r\nIt means that you can then use the `Compile` method to compute a `Delegate` in order to call the lambda at full speed.\r\n\r\n#### Using a IParameterTypeResolver\r\n\r\nUnfortunately, things can get a little bit more complicated if you want to parse the same expression without\r\nspecifying the parameter type giving us a expression like `\"x =\u003e x + 1\"`.\r\nIn this case you will need to provide to the ExpressionParser a `IParameterTypeResolver` that will resolve\r\nthe type of the parameter `x` as an integer:\r\n\r\n```csharp\r\n// Set the expression to parse\r\nvar expToParse = \"x =\u003e x + 1\";\r\n\r\n// We need to create the parser with a DictionaryParameterTypeResolver that will resolve the\r\n// parameter name using the given Dictionary.\r\nvar expressionParser = new ExpressionParser(\r\n    parameterTypeResolver: new DictionaryParameterTypeResolver(new Dictionary\u003cstring, Type\u003e()\r\n    {\r\n        { \"x\", typeof(int) },\r\n    }));\r\n\r\n// We can just parse the expression.\r\nvar expression = expressionParser.Parse\u003cFunc\u003cint, int\u003e\u003e(expToParse);\r\n```\r\n\r\n#### Using a ITypeNameResolver\r\n\r\nLet's now use a static method `Max` that is defined in `System.Math` with a full qualified name like\r\n`\"(double x, double y) =\u003e Math.Max(x, y)\"`.\r\nTo support this use case, you will need to provide a `ITypeNameResolver` that will resolve the `Math` as `System.Math` class:\r\n\r\n```csharp\r\n// Set the expression to parse\r\nvar expToParse = \"(double x, double y) =\u003e Math.Max(x, y)\";\r\n\r\n// We need to create the parser with a TypeNameResolver that will resolve type name with\r\n// the given System.Math class.\r\nvar expressionParser = new ExpressionParser(\r\n    typeNameResolver: new TypeNameResolver(typeof(Math)));\r\n\r\n// We can just parse the expression.\r\nvar expression = expressionParser.Parse\u003cFunc\u003cdouble, double, double\u003e\u003e(expToParse);\r\n```\r\n\r\n#### Using a IMethodResolver\r\n\r\nNow we want our expression to use a static method `Max` that is defined in `System.Math` omitting the class name prefix like\r\n`\"(double x, double y) =\u003e Max(x, y)\"`.\r\nTo support this use case, you will need to provide a `IMethodResolver` that will resolve the `Max` as `System.Math.Max`:\r\n\r\n```csharp\r\n// Set the expression to parse\r\nvar expToParse = \"(double x, double y) =\u003e Max(x, y)\";\r\n\r\n// We need to create the parser with a StaticMethodResolver that will resolve methods with\r\n// the System.Math class.\r\nvar expressionParser = new ExpressionParser(\r\n    methodResolver: new StaticMethodResolver(typeof(Math)));\r\n\r\n// We can just parse the expression.\r\nvar expression = expressionParser.Parse\u003cFunc\u003cdouble, double, double\u003e\u003e(expToParse);\r\n```\r\n\r\n### Expression transformation\r\n\r\n#### Inline C# Lambda expression\r\n\r\n##### One parameter expression\r\n\r\nIn the case where we would like the replace the parameter `a` from one expression like `\"a =\u003e a * 2\"` by another\r\nexpression like `\"b =\u003e b + 1\"` resulting in `\"b =\u003e (b + 1) * 2\"`, we can use the `SingleParameterInliner`.\r\n\r\n```csharp\r\n// Setup the expressions to use as input\r\nExpression\u003cFunc\u003cint, int\u003e\u003e expressionToAmend = a =\u003e a * 2;\r\nExpression\u003cFunc\u003cint, int\u003e\u003e expressionToInline = b =\u003e b + 1;\r\n\r\n// create the expression parameter in-liner.\r\nvar inliner = new SingleParameterInliner();\r\n\r\n// Amend the given expression replacing parameter 'a' with the expression to in-line resulting in the\r\n// lambda 'b =\u003e (b + 1) * 2'.\r\nvar inlinedExpression = inliner.Amend\u003cFunc\u003cint, int\u003e, Func\u003cint, int\u003e\u003e(expressionToInline, expressionToAmend);\r\n```\r\n\r\n##### Multi parameter expression\r\n\r\nIn the case where we would like to amend an expression like `\"(a, b) =\u003e a * b\"` replacing the two parameter 'a' and 'b'\r\nwith two another expressions:\r\n\r\n* using `\"c =\u003e c + 1\"` to replace 'a'\r\n* and using `\"d =\u003e d - 1\"` to replace 'b'\r\n\r\nall this resulting in `\"(c, d) =\u003e (c + 1) * (d - 1)\"`, we can use the `MultiParameterInliner`.\r\n\r\nAll it needs is a `ParameterResolver` that will be used to get the expression to in-line instead of the parameter itself:\r\n\r\n```csharp\r\n// Setup the expressions to use as input\r\nExpression\u003cFunc\u003cint, int\u003e\u003e expressionToAmend = (a, b) =\u003e a * b;\r\nExpression\u003cFunc\u003cint, int\u003e\u003e expressionToInlineForA = c =\u003e c + 1;\r\nExpression\u003cFunc\u003cint, int\u003e\u003e expressionToInlineForB = d =\u003e d - 1;\r\n\r\n// create the expression in-liner.\r\nvar inliner = new ExpressionInliner();\r\n\r\n// Setup the resolver telling that 'a' must be replaced by in-lined 'c =\u003e c + 1' lambda\r\n// and that 'b' must be replaced by in-lined 'd =\u003e d - 1' lambda.\r\nvar resolver = new ParameterResolver()\r\n    .Register(\"a\", expressionToInlineForA)\r\n    .Register(\"b\", expressionToInlineForB);\r\n\r\n// Amend the given expression replacing parameters resulting in the lambda '(c, d) =\u003e (c + 1) * (d - 1)'.\r\nvar inlinedExpression = inliner.Amend\u003cFunc\u003cint, int\u003e, Func\u003cint, int\u003e\u003e(resolver, expressionToAmend);\r\n```\r\n\r\n#### Inline Constant expression\r\n\r\nLet's say that we need to convert a Lambda Expression using an external variable like this:\r\n\r\n```csharp\r\n// Here is a variable we are going to use in a Lambda Expression.\r\nvar externalValue = 0.01d;\r\n\r\n// The expression is multiplying the input with the variable 'externalValue'.\r\nExpression\u003cFunc\u003cdouble, double\u003e\u003e expToInline = i =\u003e i * externalValue;\r\n```\r\n\r\nThe use case here is that we want to convert the expression in-lining the actual value of the variable like\r\n `i =\u003e i * 0.01d`.\r\n\r\nIt has never been simpler with the `ConstantInliner`: all we need is to call its `Amend` method:\r\n\r\n```csharp\r\n// Create the constant in-liner.\r\nvar inliner = new ConstantInliner();\r\n\r\n// Amend the expToInline.\r\nvar exp = inliner.Amend(expToInline);\r\n\r\n// That's yet, 'exp' is equal to 'i =\u003e i * 0.01d'\r\n```\r\n\r\n#### Resolve Property Name\r\n\r\nIn order to get the name of a property from a lambda like `i =\u003e i.MyProperty` we can use the `PropertyNameResolver`:\r\n\r\n```csharp\r\n\r\n// Create a instance of the resolver.\r\nvar resolver = new PropertyNameResolver();\r\n\r\n// Resolve the property name of the given lambda.\r\nvar name = resolver.GetPropertyName\u003cIMyType, string\u003e(x =\u003e x.MyProperty);\r\n\r\n// Here name is set to \"MyProperty\".\r\n\r\n```\r\n\r\n#### Expression serializer\r\n\r\nTo serialize your expression as a string, you can use the Serialize method like this:\r\n\r\n```csharp\r\n\r\nusing SoloX.ExpressionTools.Transform;\r\n\r\nExpression\u003cFunc\u003cdouble, double, double\u003e\u003e expression = (a, b) =\u003e Math.Pow(a, b);\r\n\r\nvar txt = expression.Serialize();\r\n\r\n// will give you the string:\r\n// \"(a, b) =\u003e Math.Pow(a, b)\"\r\n\r\n```\r\n\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxaviersolau%2Fexpressiontools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxaviersolau%2Fexpressiontools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxaviersolau%2Fexpressiontools/lists"}