Tenekon.MethodOverloads.SourceGenerator
0.0.6-rc.1
Prefix Reserved
dotnet add package Tenekon.MethodOverloads.SourceGenerator --version 0.0.6-rc.1
NuGet\Install-Package Tenekon.MethodOverloads.SourceGenerator -Version 0.0.6-rc.1
<PackageReference Include="Tenekon.MethodOverloads.SourceGenerator" Version="0.0.6-rc.1"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="Tenekon.MethodOverloads.SourceGenerator" Version="0.0.6-rc.1" />
<PackageReference Include="Tenekon.MethodOverloads.SourceGenerator"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add Tenekon.MethodOverloads.SourceGenerator --version 0.0.6-rc.1
#r "nuget: Tenekon.MethodOverloads.SourceGenerator, 0.0.6-rc.1"
#:package Tenekon.MethodOverloads.SourceGenerator@0.0.6-rc.1
#addin nuget:?package=Tenekon.MethodOverloads.SourceGenerator&version=0.0.6-rc.1&prerelease
#tool nuget:?package=Tenekon.MethodOverloads.SourceGenerator&version=0.0.6-rc.1&prerelease
Tenekon.MethodOverloads.SourceGenerator
A C# source generator that creates extension overloads by treating a selected parameter window as optional and emitting legal, unique subsequences. It supports matchers, bucketized output, visibility overrides, subsequence strategies, and generic substitution via SupplyParameterType.
Install
<ItemGroup>
<PackageReference Include="Tenekon.MethodOverloads.SourceGenerator" Version="x.y.z" PrivateAssets="all" />
</ItemGroup>
Quickstart
- Add
[GenerateOverloads]to a method, or[GenerateMethodOverloads(Matchers = ...)]to a type. - (Optional) Add
[OverloadGenerationOptions(...)]to control matching and output. - Build. Generated code appears as
MethodOverloads_<Namespace>*.g.cs.
Core Concepts
- Window: the parameter range that can be omitted to produce overloads.
- Matchers: define windows on matcher methods and apply them to target methods.
- Bucketization: route generated methods into a specific static partial class.
- SupplyParameterType: substitute method type parameters with concrete types before generation.
Examples
1) Basic Window
Input:
namespace Demo;
using Tenekon.MethodOverloads;
public sealed class OrderService
{
[GenerateOverloads(Begin = nameof(tenantId))]
public void CreateOrder(string orderId, string tenantId, bool requireApproval) { }
}
Output:
namespace Demo;
public static class MethodOverloads
{
public static void CreateOrder(this OrderService source, string orderId) =>
source.CreateOrder(orderId, tenantId: default(string), requireApproval: default(bool));
public static void CreateOrder(this OrderService source, string orderId, string tenantId) =>
source.CreateOrder(orderId, tenantId, requireApproval: default(bool));
public static void CreateOrder(this OrderService source, string orderId, bool requireApproval) =>
source.CreateOrder(orderId, tenantId: default(string), requireApproval);
}
2) Window Variants
Use Begin, End, BeginExclusive, EndExclusive, or the constructor GenerateOverloads(string beginEnd).
[GenerateOverloads(BeginExclusive = nameof(start), End = nameof(end))]
public void Query(int start, int end, bool includeMetadata, string? tag) { }
3) Matcher-Based Generation (Method-Level)
Input:
namespace Demo;
using Tenekon.MethodOverloads;
public sealed class UserService
{
[GenerateOverloads(Matchers = [typeof(UserMatchers)])]
public void UpdateUser(string id, string name, int level, bool active) { }
}
internal interface UserMatchers
{
[GenerateOverloads(nameof(paramB))]
void UpdateUser(int paramA, bool paramB);
}
Output:
namespace Demo;
public static class MethodOverloads
{
public static void UpdateUser(this UserService source, string id, string name, int level) =>
source.UpdateUser(id, name, level, active: default(bool));
}
4) Matcher-Based Generation (Type-Level + Static Target)
Input:
namespace Demo;
using Tenekon.MethodOverloads;
[GenerateMethodOverloads(Matchers = [typeof(MathMatchers)])]
public static class MathUtils
{
public static void Multiply(int left, int right, bool checkedOverflow) { }
}
internal interface MathMatchers
{
[GenerateOverloads(nameof(paramB))]
void Multiply(int paramA, bool paramB);
}
Output:
namespace Demo;
public static class MethodOverloads
{
extension(MathUtils)
{
public static void Multiply(int left, int right) =>
MathUtils.Multiply(left, right, checkedOverflow: default(bool));
}
}
5) Range Anchor Match Mode
RangeAnchorMatchMode.TypeOnly (default) matches by type only.
RangeAnchorMatchMode.TypeAndName requires matching names as well.
[OverloadGenerationOptions(RangeAnchorMatchMode = RangeAnchorMatchMode.TypeAndName)]
[GenerateOverloads(Matchers = [typeof(ServiceMatchers)])]
public void Call(string id, string name, bool active) { }
6) Subsequence Strategy
OverloadSubsequenceStrategy.UniqueBySignature (default) generates all unique overloads.
OverloadSubsequenceStrategy.PrefixOnly generates only prefix omissions.
[OverloadGenerationOptions(SubsequenceStrategy = OverloadSubsequenceStrategy.PrefixOnly)]
[GenerateOverloads(Begin = nameof(optionalA))]
public void Configure(int required, string? optionalA, bool optionalB) { }
7) Overload Visibility
[OverloadGenerationOptions(OverloadVisibility = OverloadVisibility.Internal)]
[GenerateOverloads(Begin = nameof(optionalA))]
public void Configure(int required, string? optionalA, bool optionalB) { }
8) Bucketization (Scoped Static Classes)
Route generated overloads into a specific static partial class:
public static partial class MyBucket
{
}
[OverloadGenerationOptions(BucketType = typeof(MyBucket))]
[GenerateOverloads(Begin = nameof(optionalA))]
public void Configure(int required, string? optionalA, bool optionalB) { }
Output:
public static partial class MyBucket
{
public static void Configure(this /* target type */ source, int required) =>
source.Configure(required, optionalA: default(string), optionalB: default(bool));
}
9) SupplyParameterType (Generic Substitution)
Replace method type parameters with concrete types in generated overloads and invocations.
public sealed class Constraint { }
public interface IService<T> { }
public sealed class Api
{
[GenerateOverloads(nameof(optionalObject))]
[SupplyParameterType(nameof(TConstraint), typeof(Constraint))]
public void Use<TConstraint>(IService<TConstraint>? service, object? optionalObject) { }
}
Output:
public static class MethodOverloads
{
public static void Use(this Api source, IService<Constraint>? service) =>
source.Use<Constraint>(service, default(object?));
}
If only some method type parameters are supplied, the overload stays generic for the remaining ones.
10) Generic Containing Types
Containing type type parameters and constraints are preserved on generated overloads.
public sealed class Container<T> where T : class, new()
{
[GenerateOverloads(nameof(optionalObject))]
public void Create(T value, object? optionalObject) { }
}
Generated overloads keep T and its constraints.
MSBuild Options
Emit attributes only (skip generation and diagnostics):
<PropertyGroup>
<TenekonMethodOverloadsSourceGeneratorAttributesOnly>true</TenekonMethodOverloadsSourceGeneratorAttributesOnly>
</PropertyGroup>
Diagnostics
Diagnostics are reported by the analyzer and surfaced during build:
MOG001Invalid window anchor.MOG002Matcher has no subsequence match.MOG003Defaults inside window.MOG004Params outside window.MOG005Ref/out/in omitted.MOG006Duplicate signature skipped.MOG007Conflicting window anchors (BeginEnd vs Begin/End).MOG008Redundant Begin and End.MOG009Begin and BeginExclusive conflict.MOG010End and EndExclusive conflict.MOG011Parameterless target method.MOG012Matchers + window anchors conflict.MOG013Invalid bucket type.MOG014Invalid SupplyParameterType usage.MOG015SupplyParameterType refers to missing type parameter.MOG016Conflicting SupplyParameterType mappings.
You can downgrade error-level diagnostics in .globalconfig if you need the project to compile with intentional violations.
Generation Rules (Summary)
- Only ordinary, non-private methods are eligible.
- Window omissions cannot drop
ref/out/inparameters. paramsmust be inside the optional window to be omitted.- Existing method signatures are not duplicated.
- Defaults inside the window are not allowed.
- Matcher usages are emitted only when the matcher type is at least
internal.
Docs
See docs/generator.md for detailed behavior and docs/acceptance-criterias.md for the acceptance project structure.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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 was computed. 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. net9.0 was computed. 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 was computed. 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. |
| .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
- 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.0.6-rc.1 | 64 | 2/16/2026 |
| 0.0.6-alpha.6 | 55 | 2/15/2026 |
| 0.0.6-alpha.4 | 39 | 2/15/2026 |
| 0.0.6-alpha.3 | 44 | 2/15/2026 |
| 0.0.6-alpha.1 | 42 | 2/14/2026 |
| 0.0.5 | 125 | 2/6/2026 |
| 0.0.5-rc.18 | 45 | 2/6/2026 |
| 0.0.5-rc.17 | 49 | 2/6/2026 |
| 0.0.5-rc.15 | 45 | 2/5/2026 |
| 0.0.5-rc.14 | 46 | 2/5/2026 |
| 0.0.5-rc.13 | 54 | 2/5/2026 |
Initial public release. Generates combinatorial extension method overloads from a marked optional parameter window, dedupes signatures, and avoids invalid overloads.