ZySharp.Metaprogramming
1.3.1
Prefix Reserved
dotnet add package ZySharp.Metaprogramming --version 1.3.1
NuGet\Install-Package ZySharp.Metaprogramming -Version 1.3.1
<PackageReference Include="ZySharp.Metaprogramming" Version="1.3.1" />
paket add ZySharp.Metaprogramming --version 1.3.1
#r "nuget: ZySharp.Metaprogramming, 1.3.1"
// Install ZySharp.Metaprogramming as a Cake Addin #addin nuget:?package=ZySharp.Metaprogramming&version=1.3.1 // Install ZySharp.Metaprogramming as a Cake Tool #tool nuget:?package=ZySharp.Metaprogramming&version=1.3.1
ZySharp Metaprogramming
A modern C# metaprogramming library.
Enhanced Lambda Type Inference
The C# language currently is not completely able to automatically infer the return type of anonymous methods when using a var
declaration or when returning curried functions. The helper methods in the ZySharp.Metaprogramming.Lambda
class can be used to work around this limitation.
// Expression<Func<>>
var e = Lambda.Expr((int x) => x == 42);
var e = Lambda.Expr((int x) => new { Value = x });
var e = Lambda.Expr((int x) => Lambda.Func((int y) => x + y));
// Func<>
var d = Lambda.Func((int x) => x == 42)
var d = Lambda.Func((int x) => new { Value = x });
var d = Lambda.Func((int x) => Lambda.Func((int y) => x + y));
Expression Concatenation and Invocation
When creating dynamic LINQ expressions, it is often useful to use foreign lambda expressions inside an outer expression. While this is somewhat possible (.Compile().Invoke(...)
), most third-party libraries (e.g. LINQ to Entities
) are not able to understand the resulting expression tree. The ZySharp.Metaprogramming.Expr
class provides a set of simple functions to solve this problem.
Expression Concatenation
// Expression<Func<>>
var inner = Lambda.Expr((int x) => x == 42);
var outer = Lambda.Expr((IQueryable<int> x) => x.Where(inner));
// :. Expression<Func<int, bool>>
var result = outer.Expand(); // x => x.Where(x => x == 42)
// Func<>
var inner = Lambda.Expr((int x) => x == 42);
var outer = Lambda.Expr((IEnumerable<int> x) => x.Where(inner.Compile()));
// :. Func<int, bool>
var result = outer.Expand(); // x => x.Where(x => x == 42)
Expression Invocation
var lower = Lambda.Expr((int x) => x >= 10);
var upper = Lambda.Expr((int x) => x <= 42);
var outer = Lambda.Expr((IQueryable<int> x) => x.Where(x => lower.Invoke(x) && upper.Invoke(x)));
var result = outer.Expand(); // x => x.Where(x => x >= 10 && x <= 42)
Dynamic Expression Invocation
In the following example, GetPredicateExpressionWithParam()
is evaluated at runtime (when .Expand()
is called). The resulting expression is then integrated into the outer expression tree. During this process, all captured variables (num42
) are also evaluated.
private static Expression<Func<int, bool>> GetPredicateExpressionWithParam(int number)
{
return x => x == number;
}
var num42 = 42;
var outer = Lambda.Expr((IQueryable<int> x) => x.Where(x => GetPredicateExpressionWithParam(num42).Invoke(x)));
var result = outer.Expand(); // x => x.Where(x => x == 42)
Expression Tree Comparison
By default, expression trees can only be compared by reference. To be able to e.g. store semantically equivalent expression trees in a dictionary, the ZySharp.Metaprogramming.ExprEqualityComparer
implements the IEqualityComparer<T>
interface for the Expression
class.
var x = Lambda.Expr((int a, int b) => a + b);
var y = Lambda.Expr((int c, int d) => c + d);
ExprEqualityComparer.Default.Equals(x, y); // true
var z = Lambda.Expr((int a, int b) => a + a);
ExprEqualityComparer.Default.Equals(x, z); // false
All built-in Expression
types except DynamicExpression
are supported.
Versioning
Versions follow the semantic versioning scheme.
License
ZySharp.Metaprogramming is licensed under the MIT license.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Bcl.HashCode (>= 1.1.1)
- ZySharp.Validation (>= 1.3.1)
-
net6.0
- ZySharp.Validation (>= 1.3.1)
-
net7.0
- ZySharp.Validation (>= 1.3.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.