Skip to content

Interceptors C# 12.0code generation

Allow a method to declare it replaces another method.

Interceptors allow a method to declare it should be used in place of a specific call elsewhere in the project's source code by identifying that call's location with the InterceptsLocationAttribute.

This is useful for code generation scenarios where code-generated methods could add new functionality but could not replace or remove existing code unless that code was specifically written in a way to permit replacement or removal.

Code ​

csharp
// User-written "Program.cs"
partial class Program
{
    public void PerformOperation()
    {
        Initialize();
    }

    public void Initialize()
    {
        // ...
    }
}

// Code-generated "Program.generated.cs"
static class ProgramInterceptors
{
    // The generator gets the location of the Initialize() call above
    // from SemanticModel.GetInterceptableLocation()
    [InterceptsLocation(version: 1, data: "...")]
    public static void SpecialInitialize(this Program program)
    {
        // ...
    }
}
csharp
// User-written "Program.cs"
partial class Program
{
    private Action? initializer;
    partial void PerformOperationStartHook();

    public void PerformOperation()
    {
        initializer = Initialize;
        PerformOperationStartHook();
        initializer();
    }

    public void Initialize()
    {
        // ...
    }
}

// Code-generated "Program.generated.cs"
partial class Program
{
    partial void PerformOperationStartHook()
    {
        initializer = SpecialInitialize;
    }

    public void SpecialInitialize()
    {
        // ...
    }
}

Notes ​

  • The interceptor must be a static method whose signature matches the intercepted call. For instance methods, the first parameter is the receiver and is annotated with this just like an extension method C# 3.0
  • Projects opt in by listing the interceptor's namespace in the <InterceptorsNamespaces> MSBuild property (<InterceptorsPreviewNamespaces> in the .NET 8 SDK, still accepted as an alias)
  • InterceptsLocationAttribute is declared by the generator itself, typically as a file-local type C# 11.0
  • The location data is an opaque encoded string produced by the compiler API rather than written by hand; the original design used a file path, line and column instead

More information ​

Powered by Intracia