SpawnDev.GenericInvocation 1.0.0

Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
dotnet add package SpawnDev.GenericInvocation --version 1.0.0
                    
NuGet\Install-Package SpawnDev.GenericInvocation -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SpawnDev.GenericInvocation" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SpawnDev.GenericInvocation" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="SpawnDev.GenericInvocation" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SpawnDev.GenericInvocation --version 1.0.0
                    
#r "nuget: SpawnDev.GenericInvocation, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SpawnDev.GenericInvocation@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SpawnDev.GenericInvocation&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=SpawnDev.GenericInvocation&version=1.0.0
                    
Install as a Cake Tool

SpawnDev.GenericInvocation

NuGet Version License

A ultra-high-performance, zero-allocation reflection utility for .NET 8, 9, and 10 that bridges the gap between runtime Type variables and compile-time generic (<T>) method signatures.

By utilizing one-time compiled Expression Trees and cached non-boxing generic bridges, SpawnDev.GenericInvocation completely avoids the heavy runtime performance penalties of MethodInfo.Invoke and the memory churn of the C# dynamic keyword call-site binder.

🚀 Why Use It?

In advanced architecture patterns (like high-throughput Marshallers, Serializers, or JS-Interop pipelines), you often encounter situations where you know an object's destination type only at runtime, but you need to feed it into a heavily optimized, strongly-typed method blueprint:

// You have this at runtime:
Type runtimeType = typeof(double);

// And you need to invoke this without causing a massive bottleneck:
async ValueTask<T> WriteTypedValue<T>() { ... }

The Old Ways vs. SpawnDev

  1. MethodInfo.Invoke: Extremely slow. Forces the runtime to run heavy security validation checks and box value types (like primitives or ValueTask) into heap-allocated object structures on every single call.
  2. dynamic Dispatch: Faster on warm paths due to DLR caching, but introduces silent heap allocations, state-machine tracking overhead, and forces struct-boxing on value-type tasks like ValueTask<T>.
  3. SpawnDev.GenericInvocation: Inspects metadata and compiles a native execution lambda expression exactly once per type combination. Subsequent hot-path invocations execute at raw, near-handwritten speed with zero allocation overhead.

⚡ Performance Benchmarks

Target Frameworks: .NET 8, 9, and 10 | 1,000,000 Hot-Path Loop Iterations calling ValueTask<T>

Implementation Strategy Cost Per Call Total Elapsed Time
Hardcoded Direct Native Call (Baseline Limit) ~0.44 μs 4,472,600 μs
SpawnDev.GenericInvocation ~2.41 μs 2,414,099 μs
Dynamic Keyword (dynamic) Unwrapping ~4.36 μs 4,418,700 μs

By eliminating call-site binder churn and preventing value-type unboxing, SpawnDev.GenericInvocation delivers a ~38% raw performance leap over standard dynamic async unwrapping strategies.


💻 Quick Start & Examples

1. Single Type Parameter Invocations

using SpawnDev.GenericInvocation;

// Create a delegate targeting your generic method signature
var myMethod = ((Delegate)MyAction<object>).InvokeGenericAsync(typeof(double));

async ValueTask<T> MyAction<T>() 
{
    Console.WriteLine(\$"Executed natively with type: {typeof(T).Name}");
    return default;
}

2. Multi-Type Parameter Fallbacks

The library intelligently handles single and multi-type cached dimensions dynamically without forcing array mutations on the heap on cache hits:

Type[] runtimeTypes = [typeof(string), typeof(int)];

// Dispatches seamlessly into multi-generic signatures
await myMethodGroup.InvokeGenericAsync(runtimeTypes, "Hello World", 42);

3. Native Task & ValueTask Auto-Unwrapping

Whether your generic target returns a Task<T>, ValueTask<T>, or synchronous primitives, the under-the-hood expression compiler automatically extracts the inner value seamlessly:

// Returns the actual unwrapped type without executing a slow reflection lookup on Task.Result
object? result = await myDelegate.InvokeGenericAsync(typeof(int));

⚙️ Features Under the Hood

  • Zero Array Heap Allocations: Leverages .NET 10 Span<object?> parameter layouts combined with conditional key-cloning to ensure that checking cache dictionaries is entirely garbage-collection silent.
  • Auto-Target Resolution: Native support for instance methods, static methods, and complex captured local functions alike without triggering delegate targeting binding failures (Arg_DlgtTargMeth).
  • Built for the Future: Designed specifically with lightweight runtime features optimized for high-throughput UI wrappers, framework components, and Blazor WebAssembly environments.

📄 License

This project is licensed under the MIT License.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  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.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 109 8/14/2026
1.0.0 102 8/12/2026

v1.0.0