This package delivers a robust C# parsing and expression execution API designed for Unity compatibility across multiple platforms. Implemented in C# with no external dependencies, it maintains broad compatibility with modern Unity versions and .NET frameworks.
This package is available for purchase on the Unity Asset Store. A valid license is required for use in any project. See License.md for details.
Evaluate simple C# expressions immediately:
using GameDevWare.Dynamic.Expressions.CSharp;
var result = CSharpExpression.Evaluate<int>("2 * (2 + 3) << 1");
// Returns 20Parse an expression once and execute it multiple times with high performance:
using GameDevWare.Dynamic.Expressions.CSharp;
using System.Linq.Expressions;
var mathExpr = "Math.Max(x, y)";
var exprTree = CSharpExpression.ParseFunc<double, double, double>(mathExpr, arg1Name: "x", arg2Name: "y");
// Returns Expression<Func<double, double, double>>
var func = exprTree.CompileAot();
// Returns Func<double, double, double>
var result = func(10.5, 20.0); // 20.0- iOS (IL2CPP)
- Android (Mono/IL2CPP)
- WebGL
- Windows / macOS / Linux
- Consoles (Nintendo Switch, PS4/PS5, Xbox)
Important
AOT Platforms (iOS, WebGL, IL2CPP):
Projects targeting AOT compilation require a link.xml file to prevent code stripping. A sample is provided in the package. Refer to Unity's documentation on IL code stripping for more context.
The parser implements C# 4.0+ grammar with support for:
- Operations: Arithmetic, bitwise, logical, Conditional (?:), and Null-coalescing (??).
- Invocations: Methods, delegates, and constructors.
- Access: Properties, fields, and indexers.
- Types: Casting, is/as operators,
typeof(), anddefault(). - Contexts: Checked/Unchecked blocks.
- Advanced: Null-conditional (?. and ?[]), Power operator (
**), and Lambda expressions. - Generics: Support for generic types and methods (requires explicit type specification; type inference is not supported).
- Serialization: Pack/Unpack expressions into serializable structures.
For security, the parser restricts type access by default. Additional types must be registered:
// Register specific types
var typeResolver = new KnownTypeResolver(typeof(Mathf), typeof(Time));
CSharpExpression.Evaluate<float>("Mathf.Clamp(Time.time, 0f, 1f)", typeResolver);
// Or allow an entire assembly
var assemblyResolver = new AssemblyTypeResolver(typeof(UnityEngine.Vector3).Assembly);High-performance execution on AOT platforms (iOS, WebGL, Consoles) is achieved via CompileAot():
var expr = (Expression<Func<Vector3>>)(() => new Vector3(1f, 1f, 1f));
var fn = expr.CompileAot(); // Uses AOT-safe execution if needed- Only
Expression<Func<...>>andExpression<Action<...>>are supported. - Register required delegate types:
AotCompilation.RegisterFunc<int, string>();. - Use
AotCompilation.RegisterForFastCall<TTarget, TResult>()for maximum performance on critical paths.
- Open Window > Package Manager.
- Select Packages: My Assets.
- Find C# Eval() and click Download/Import.
Install-Package GameDevWare.Dynamic.ExpressionsWe are continuously improving the package. Planned features include:
- Generic type inference
- C# 6.0+ extended syntax support
- Extension method support
Support: support@gamedevware.com
- Fix: Correctly format new expression types (Member/List Init) from syntax trees.
- Change: Internal renaming of
AssignmenttoAssignmentBinding(backward compatible).
- Breaking: Distributed as a Unity Package instead of a legacy
.dll. - Feature: Added support for Object and Collection Initializers.
- Chore: Increased C# language support and raised minimum .NET version to 4.6+.
- Feature: Added
globalparameter for context-aware expressions. - Fix: Standardized
arg4Namenaming across methods.