C# 12 Interceptors ! An insane feature !

C# 12 Interceptors ! An insane feature !

4 min read

Visual Studio 17.7 Preview 3 and .NET 8 Preview 6 continue the evolution of C# 12. I am personally happy with all the new features in .NET 8 and C#12 except for one of them! Let me tell you which one and then explain why.

C# 12 Interceptors

This feature can be so tricky and harmful if you do not know how to use it or forget what you have done last month for example. Teamwork also can be a hassle if one of the team members uses this feature in an uncontrolled way and leave the team or forget what he/she has done or even where in the solution this piece of code has been used!

Talking and theory are enough, let me show you how can it be a danger in your code in a real scenario, but before that, I need to explain what is C# 12 Interceptors !.

Interceptors allow specific method calls to be rerouted to different codes. Attributes specify the actual source code location so interceptors are generally appropriate only for source generators. You can read the interceptors proposal to learn more about how interceptors work.

If this explanation is not clear enough, do not worry, you will see this new feature in a small project soon.

First of all, install .NET 8 SDKs and then make sure your Visual Studio 17.7 Preview 3 also is installed and working properly. In the second, create a simple Console Application.

Do not forget to change the framework to .NET 8 (PreView) like below.

Click on Create, then your simple console application is ready.

I have created a very simple Student class like below.

If you look at the screen below, you will notice how I use this class and Enroll method as well.

Since the Interceptors is one of the C# 12 features and it is still not ready to use, I have tried to ease the implementation so I have added a Helper class to the solution like below.

Now, add a CodeGenerator class to the solution and then the game is going to be started!

I have used the InterceptsLocation attribute like this :

[InterceptsLocation("""C:\Users\Ali\source\repos\InterceptorsPreviewFirstTry\Program.cs""", line: 7, character: 16)]

The first parameter is the path and name of the Program.cs file that contains my entire code and implementation. A line means the line in this file that I am pointing to and the character is the number of characters that you can see in IDE like below!

this means I am going to reroute the second method which is located in line 7 and character 15 by Interceptors so instead of firing the respected method the other method that I have created by Interceptors attribute would be fired !!!.

Real method content :  Console.WriteLine($"This Student {studentName} has been registered");

Interceptors content : Console.WriteLine($"This is a new way of Student {StudentName} registration");

Before running the app, you need to change your csproj file to be able to fire .NET 12 preview features.

<PropertyGroup>
  <OutputType>Exe</OutputType>
  <TargetFramework>net8.0</TargetFramework>
  <ImplicitUsings>enable</ImplicitUsings>
  <Nullable>enable</Nullable>
  <LangVersion>preview</LangVersion>
  <Features>InterceptorsPreview</Features>
</PropertyGroup>

You are ready to run and see the strange result now!

look at the second message below

```
//Program.cs
var studentExample = new Student();

studentExample.Enroll("Ali");
studentExample.Enroll("Hasan");
studentExample.Enroll("Hasan");
studentExample.Enroll("Reza");

public class Student
{
    public void Enroll(string studentName)
    {
        Console.WriteLine($"This Student {studentName} has been registered");
    }
}

//Helper.cs
namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
    public sealed class InterceptsLocationAttribute(string filePath, int line, int character) : Attribute
    {
    }
}

//CodeGenerator.cs
using System.Runtime.CompilerServices;
namespace InterceptorsPreviewFirstTry
{
    public static class CodeGenerator
    {
        [InterceptsLocation("""C:\Users\Ali\source\repos\InterceptorsPreviewFirstTry\Program.cs""", line: 7, character: 16)]
        public static void EnrollInterceptor(this Student StudentExample, string StudentName)
        {
            Console.WriteLine($"This is a new way of Student {StudentName} registration");
        }
    }

}

Since I said reroute the code at line 7 character 15 and this is the place of locating the second method the attribute content has been fired !!!

I think you understand why this feature can be tricky and a little bit smelly! If someone reroutes a line of code to somewhere else and then forgot it, how other team members can find the reason for this change in the attitude of the method at that line and character ?!. You can simply prank your Colleague with this feature or even confuse yourself for a while! Imagine you replace, add or remove the line of code but forget to remove the interceptor attribute or comment it out! Then ?.

This was a short story about C# 12 Interceptors and its usage but with a conservative mindset. I will show you its power and usage in a positive way also soon.

The whole source code in GitHub :

Did you find this article valuable?

Support Bug And Fix by becoming a sponsor. Any amount is appreciated!