akanse.GenericSpecializationGenerator 0.1.4

dotnet add package akanse.GenericSpecializationGenerator --version 0.1.4
                    
NuGet\Install-Package akanse.GenericSpecializationGenerator -Version 0.1.4
                    
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="akanse.GenericSpecializationGenerator" Version="0.1.4">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="akanse.GenericSpecializationGenerator" Version="0.1.4" />
                    
Directory.Packages.props
<PackageReference Include="akanse.GenericSpecializationGenerator">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
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 akanse.GenericSpecializationGenerator --version 0.1.4
                    
#r "nuget: akanse.GenericSpecializationGenerator, 0.1.4"
                    
#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.
#addin nuget:?package=akanse.GenericSpecializationGenerator&version=0.1.4
                    
Install akanse.GenericSpecializationGenerator as a Cake Addin
#tool nuget:?package=akanse.GenericSpecializationGenerator&version=0.1.4
                    
Install akanse.GenericSpecializationGenerator as a Cake Tool

GenericSpecializationGenerator

<img src="https://img.shields.io/badge/-GitHub-blue.svg?logo=github" />

<img src="https://img.shields.io/badge/-NuGet-019733.svg?logo=nuget" />

Provides generic type specialization.

What's this?

This is a source generator that achieves specialization of .Net generic methods, similar to template specialization in C++.

Considering the nature of JIT, it can generate source code with very low overhead, especially in release builds.

Usage

using GenericSpecialization.DebugApp;

partial class SampleInstanceClass
{
    // Add `PrimaryGenericAttribute` to generic method declaration
    // with a parameter of the method name which will be called for default code path.
    [PrimaryGeneric(nameof(FooDefault))]
    public partial void Foo<T>(T input);

    // Define default implementation of target generic method.
    private void FooDefault<T>(T input)
    {
        Console.WriteLine($"default");
    }

    // Write non-generic method which has same signature with the closed of target generic method declaration.
    // They will be detected automatically and be treated as implementation of generic specialization.
    private void Foo(int input)
    {
        Console.WriteLine($"int specialized");
    }

    private void Foo(double input)
    {
        Console.WriteLine($"double specialized");
    }

    // When derived types are included, the priority is determined based on the standard overload resolution order.
    private static void Foo(List<double> input)
    {
        Console.WriteLine($"List<double> specialized");
    }

    private static void Foo(IList<double> input)
    {
        Console.WriteLine($"IList<double> specialized");
    }

    private static void Foo(IEnumerable<double> input)
    {
        Console.WriteLine($"IEnumerable<double> specialized");
    }
}

Against the preceding code, this generator will generate such as following code:

// <auto-generated/>
#nullable enable
#pragma warning disable CS8600
#pragma warning disable CS8601
#pragma warning disable CS8602
#pragma warning disable CS8603
#pragma warning disable CS8604
using System.Runtime.CompilerServices;
namespace GenericSpecializationGenerator.DebugApp;

partial class SampleInstanceClass
{
    [MethodImpl(MethodImplOptions.AggressiveOptimization)]
    public partial void Foo<T>(T input)
    {
        if(typeof(T) == typeof(int))
        {
            var _input = Unsafe.As<T, int>(ref input);
            Foo(_input);
            return;
        }
        if(typeof(T) == typeof(double))
        {
            var _input = Unsafe.As<T, double>(ref input);
            Foo(_input);
            return;
        }
        if(typeof(System.Collections.Generic.List<double>).IsAssignableFrom(typeof(T)))
        {
            var _input = Unsafe.As<T, System.Collections.Generic.List<double>>(ref input);
            Foo(_input);
            return;
        }
        if(typeof(System.Collections.Generic.IList<double>).IsAssignableFrom(typeof(T)))
        {
            var _input = Unsafe.As<T, System.Collections.Generic.IList<double>>(ref input);
            Foo(_input);
            return;
        }
        if(typeof(System.Collections.Generic.IEnumerable<double>).IsAssignableFrom(typeof(T)))
        {
            var _input = Unsafe.As<T, System.Collections.Generic.IEnumerable<double>>(ref input);
            Foo(_input);
            return;
        }
        FooDefault(input);
        return;
    }
}

Rules

  • Both of void-return and non-void-return methods are supported.
  • Both of instance and static methods are supported.
    • If primary generic method is an instance method, both of instance and static methods are available as specialization or default.
    • If primary generic method is a static method, only static methods are available as specialization or default.
  • Primary generic method declaration must has accessibility modifier.
  • Generic specialization method must has same signature with primary generic method except that the generic type arguments are replaced by concrete types.
  • Generic specialization method must be in the same class with primary generic method declaration.

Limitation

These might be changed in future.

  • Partial specialization is not supported now.
    • where only some of the multiple type arguments are determined
    • where type constraints become stricter instead of concrete types being substituted

License

Apache License Version 2.0

Release Note

v0.1.0

  • Adds a source generator to add GenericSpecialization.PrimaryGenericAttribute class and generate generic specialization code.

v0.1.1

  • Fixes some bugs
    • Adds framework version check for MethodImplOptions.AggressiveOptimization
    • Supports type constraints

v0.1.2

  • Fixes to supports overloading

v0.1.3

  • Supports parameter modifiers (ref/in/out)

v0.1.4

  • Supports struct/interface
  • Supports inner type
There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has 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
0.1.4 107 4/4/2025
0.1.3 56 3/15/2025
0.1.2 74 3/15/2025
0.1.1 138 3/13/2025
0.1.0 152 3/11/2025