This package is available for purchase on the Unity Asset Store. A valid license is required for use in any project.
This package delivers a C# parsing and expression execution API designed for Unity compatibility across multiple platforms. Implemented in C# 3.5 with no external dependencies, it maintains broad compatibility with Unity versions and .NET frameworks.
• iOS
• Android
• WebGL
• Windows/macOS/Linux
The solution should function on additional Unity-supported platforms.
Important Note for AOT Platforms (iOS, WebGL, IL2CPP):
Projects targeting AOT compilation require inclusion of a link.xml file in the project root directory. Refer to Unity's documentation on IL code stripping for additional context.
• CSharpExpression
- Evaluate
 - Parse
• AotCompilation - RegisterFunc
 - RegisterForFastCall (performance optimization)
 
Expression Parsing:
var mathExpr = "Math.Max(x, y)"; var exprTree = CSharpExpression.Parse<double, double, double>(mathExpr, arg1Name: "x", arg2Name: "y"); // Returns Expression<Func<double, double, double>> var expr = exprTree.CompileAot(); // Returns Func<double, double, double>
Expression Evaluation:
var arifExpr = "2 * (2 + 3) << 1 + 1 & 7 | 25 ^ 10"; var result = CSharpExpression.Evaluate<int>(arifExpr); // Returns 19
The parser implements C# 4 grammar with support for:
• Arithmetic, bitwise, and logical operations
• Conditional and null-coalescing operators 
• Method/delegate/constructor invocation
• Property/field access and indexers 
• Type operations (casting, conversion, is/as/typeof/default)
• Expression grouping and checked/unchecked contexts 
• Type aliases and null-conditional operators 
• Power operator (**)
• Lambda expressions 
• Literal values (true, false, null)
Type Support:
• Nullable types
• Generics
• Enumerations
Note: Type inference is not implemented - explicit generic parameter specification is required.
For security, the parser restricts type access to:
• Argument types
• Primitive types
• Math, Array, and Func<> types
Additional types require specification through the typeResolver parameter:
var typeResolver = new KnownTypeResolver(typeof(Mathf), typeof(Time)); CSharpExpression.Evaluate<int>("Mathf.Clamp(Time.time, 1.0f, 3.0f)", typeResolver);
Full namespace access can be enabled via AssemblyTypeResolver:
var typeResolver = new AssemblyTypeResolver(typeof(UnityEngine.Application).Assembly);
Security Note: System.Type operations will throw exceptions unless System.Type explicitly added as a known type.
The package enables compilation and execution of System.Linq.Expression expressions in AOT environments:
var expr = (Expression<Func<Vector3>>)(() => new Vector3(1.0f, 1.0f, 1.0f)); var fn = expr.CompileAot(); // Returns Func<Vector3>
AOT Environment Requirements (iOS, WebGL and most console platforms):
- Only Expression<Func<...>> delegate types supported
 - Only static methods using primitives arguments receive optimization
 - All referenced members must be visible to Unity's static analyzer to prevent eager IL code stripping
 ⚠️ Required link.xml configuration (see above)
See Also
WebGL and iOS:
• Func<> lambdas limited to 4 arguments
• Instance methods incur reflection overhead
• Value types experience moderate boxing
Preparation for AOT Execution:
AotCompilation.RegisterFunc<int, bool>(); // Enables Func<int, bool> in expressions
Unity 2020年3月2日 Workaround:
#if ((UNITY_WEBGL || UNITY_IOS || ENABLE_IL2CPP) && !UNITY_EDITOR GameDevWare.Dynamic.Expressions.AotCompilation.IsAotRuntime = true; #endif
Method invocation performance can be enhanced through signature registration:
// Supports up to 3 arguments AotCompilation.RegisterForFastCall<MyClass, ReturnType>(); AotCompilation.RegisterForFastCall<MyClass, Arg1Type, ReturnType>(); // Additional signatures...
Example:
public class MyVectorMath { public Vector4 Dot(Vector4 vector, Vector4 vector); public Vector4 Cross(Vector4 vector, Vector4 vector); public Vector4 Scale(Vector4 vector, float scale); } // register Dot and Cross method signatures AotCompilation.RegisterForFastCall<MyVectorMath, Vector4, Vector4, Vector4>(); // register Scale method signature AotCompilation.RegisterForFastCall<MyVectorMath, Vector4, float, Vector4>();
• Expression serialization (completed)
• Void expression support (completed)
• Future enhancements:
- Delegate construction from method references
 - Generic type inference
 - C#6 syntax support
 - Extension method support
 - Type/list initializers
 
Feature suggestions may be submitted to support@gamedevware.com.
You can send suggestions at support@gamedevware.com
(削除) Expression serialization (削除ここまで)(削除) Void expressions (System.Actiondelegates) (削除ここまで)- Parser: Delegate construction from method reference
 - Parser: Type inference for generics
 - Parser: Full C#6 expression syntax
 - Parser: Extension methods
 - Parser: Type initializers, List initializers
 
- fix: fixed netcore related error with enumerable.empty
 - feature: added optional 
globalparameter to all CSharpExpression methods to allow specify global object for expression. - test: removed flaky test with double.tostring() comparison
 - fix: fixed typo in 
arg4NameinCSharpExpression.ParseFunc{4}andCSharpExpression.ParseAction{4} 
- fix: fixed error with instantiated generic method on types (which is impossible in normal conditions, but fine for Unity AOT runtime).
 
- feature:made AotCompilation.IsAotRuntime is mutable, this will allow to signal for AOT runtime and suppress further checks.
 
- feature: added public CSharpExpression.Format method for SyntaxTreeNode
 
- changed order or SyntaxTreeNode fields and added "original C# expression" field to parsed AST.
 - refactored C# expression rendering to support null-propagation expressions, type aliases (int, byte, object ...),
 - renamed "Render" methods to "FormatAsCSharp". Now it is "formatting"
 - moved c# "formatting" methods to CSharpExpression class
 - mark old "Parse" functions as errors
 - mark old "Render" methods as obsolete
 - renamed CSharpExpressionFormatter to CSharpExpressionFormatter
 - fixed indexer experssion rendering
 - refactored NameUtils to properly render C# type names
 
- renamed ParseTreeNode.Lexeme to .Token
 - renamed few member of TokenType for better clarity
 - added documentation file in Unity project assets
 - changed 'propertyOrFieldName' attribute to 'name' in SyntaxTreeNode
 - renamed PropertyOfFieldBinder to MemberBinder
 - changed 'PropertyOrField' expression type to 'MemberResolve' in SyntaxTreeNode
 - added backward compatibility checks in all related classes
 
- added protection against wrong expressions like 'a b' which later bound as 'b'
 - fixed some tokenization errors:
 - 
- 'issa'scanned as 'is'[Operator] and 'sa'[Identifier], now as 'issa'
 
 - 
- '.09' scanned as '.'[Operator] and '09'[Number], now as '0.09'
 
 - 
- '0.1x' scanned as '0.1'[Number] and 'x'[Identifier], now cause error
 
 - added method calls on numbers (example 1.ToString())
 - added short number notation (example '.9' for '0.9')
 - added '@' prefix for identifiers (example '@is') https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/verbatim
 - done small Tokenizer optimization (reduced string allocation during scanning)
 
- added ExpressionPacker type. This type allows packing/unpacking expressions into primitive structures (Dictionaries, Arrays...). These structures could be serialized and wired by network or stored for future use.
 - added better error message for some binding cases
 - denying call to 'Type.InvokeMember' if 'Type' is not within 'known types'.
 
- fixed conditional operator (a ? b : c) parsing with method call in place of 'b'
 
- fixed IL2CPP compilation error due _Attribute interface complilation failure
 - added few interfaces to AOT.cs file for better AOT coverage
 
Features
- added support for void expressions (Action<> delegates)
 - added support of '.NET Standart 1.3' and '.NET Core 2.0' platforms
 
- Release version, no actual changes except readme.md
 
- added more descriptive message for member binding error
 - added autodoc comments for public members
 - hid 
ReadOnlyDictionaryfrom public access - removed Unity WebGL #if for unsigned types. Unity's bug was fixed.
 - added support for generic types and generic methods
 - added nullable types and 
?suffix support 
CSharpExpression.Evaluate<int?>("default(int?)"); // -> null
- added lambda expressions. Syntax is 
() => xandnew Func(a => x) - added support for expression's parameter re-mapping with lambda expression syntax:
 
CSharpExpression.Evaluate<int, int, int>("(x,y) => x + y", 2, 2); // -> 4
- added support for 
Func<>lambdas for AOT environments - added additional constructor to Binder class
 
public Binder(Type lambdaType, ITypeResolver typeResolver = null);
- added 
ArgumentsTree.ToString()method - added aliases for build-in types. Aliases resolved during binding phase inside 
Binder.Bind()method. 
CSharpExpression.Evaluate<int>("int.MaxValue");
- fixed error with wrongly resolved types (only by name) in KnownTypeResolver
 - fixed bug with ACCESS_VIOLATION on iOS (Unity 5.x.x IL2CPP)
 - fixed few Unity 3.4 related errors in code
 - fixed 'new' expression parsed with error on chained calls new a().b().c()
 - fixed some cases of lifted binary/unary/conversion operations
 - fixed some AOT'ed operations on System.Boolean type
 - fixed null-propagation chains generate invalid code
 - fixed some edge cases of resolving nested generic types
 - fixed error with types without type.FullName value
 - fixed Condition operator types promotion
 - fixed Power operator types promotion and null-lifting
 - fixed enum constants threated as underlying types during binary/unary operations
 
- ParserNode renamed to ParseTreeNode
 - ExpressionTree renamed to SyntaxTreeNode
 - ExpressionBuilder renamed to Binder
 - ITypeResolutionService renamed to ITypeResolver
 - ITypeResolver.GetType removed
 - ITypeResolver now could be configured with TypeDiscoveryOptions
 
- fixed error them creating nullable types via "new" keyword
 - fixed Embedded Resource addressing problem on IL2CPP WebGL (localized error messages)
 - fixed some cases of nullable types binding
 - fixed Enum member resolution
 - added Power(
**) operator into C# syntax 
CSharpExpression.Evaluate<int>("2 ** 2"); // -> 4
- added TypeResolutionService chaining for better KnownTypes re-use
 
- fixed error with nulled constants after first call for AOT-ted expression.
 - added ToString() impl for ExpressionTree
 
- added Null-conditional Operators (example: a.?b.?.c)
 - fixed array indexing expressions
 - added array types support in type expressions ('convert', 'typeof', 'is' etc.)
 
Install-Package GameDevWare.Dynamic.Expressions
Unity:
Please send any questions at support@gamedevware.com