Source Generators și Interceptori în C#: Metaprogramare la Compilare și Eliminarea Reflexiei în C# (.NET)

Sintaxă Modernă și OOP C# 12 / .NET 8

Ghid complet pentru metaprogramare la compilare în C#: generarea dinamică de cod cu Incremental Source Generators și înlocuirea apelurilor de metodă la compilare prin noul mecanism experimental de Interceptors în C# 12.

Sintaxă C#
[InterceptsLocation(...)] | IIncrementalGenerator | Roslyn Source Generators

Framework-urile tradiționale de .NET se bazau masiv pe Reflexie la Runtime (Reflection) pentru a descoperi controlere, a serializa obiecte sau a injecta dependențe. Reflexia este lentă, consumă multă memorie și blochează compilarea nativă AOT deoarece compilatorul nu poate deduce ce clase sunt folosite dinamic.

Ecosistemul modern C# a migrat către Incremental Source Generators (încorporați în compilatorul Roslyn) și Interceptori (Interceptors) din C# 12, mutând inspecția de cod direct la momentul compilării.

Cum Funcționează un Source Generator Incremental
using Microsoft.CodeAnalysis;

// Generatorul rulează în interiorul compilatorului Roslyn în timp ce tastați codul în IDE:
[Generator]
public class AutoEnumDescriberGenerator : IIncrementalGenerator
{
    public void Initialize(IncrementalGeneratorInitializationContext context)
    {
        // 1. Filtrăm sintactic exclusiv declarațiile de tip Enum:
        var enumDeclarations = context.SyntaxProvider
            .CreateSyntaxProvider(
                predicate: (s, _) => s is Microsoft.CodeAnalysis.CSharp.Syntax.EnumDeclarationSyntax,
                transform: (ctx, _) => ctx.Node
            );

        // 2. Emitem cod C# pur generat care se compilează împreună cu proiectul:
        context.RegisterSourceOutput(enumDeclarations, (spc, node) => {
            spc.AddSource("EnumExtensions.g.cs", "// Cod C# generat automat la compilare");
        });
    }
}

Ce Sunt Interceptorii în C# 12?

Un Interceptor permite compilatorului să redirecționeze un apel de metodă specific (identificat prin fișier sursă, număr de linie și coloană) către o implementare alternativă optimizată, fără a modifica codul sursă original apelat de utilizator:

// În codul aplicației scrieți simplu:
app.MapGet("/utilizatori", () => "Lista utilizatori");

// În culise, un Interceptor din ASP.NET Core 8 înlocuiește acest apel cu:
// Rutare directă compilată nativ, eliminând Expression Trees și reflexia la runtime!