Generic Math și Interfețe Statice Virtuale în C#: INumber și Calcule Numerice Abstracte în C# (.NET)

Bazele limbajului și I/O C# 11 / .NET 7

Ghid complet pentru Generic Math în C# 11 și .NET 7+: utilizarea metodelor statice abstracte în interfețe, scrierea algoritmilor numerici universali cu INumber<T> și eliminarea supraîncărcărilor repetitive.

Sintaxă C#
T Aduna<T>(T a, T b) where T : INumber<T> => a + b; | static abstract T Zero { get; }

Timp de două decenii, una dintre cele mai frustrante limitări din C# a fost imposibilitatea de a scrie algoritmi generici peste tipuri numerice: dacă scriați o funcție T CalculeazaSuma<T>(T a, T b), codul nu compila deoarece operatorul + nu era definit pe un parametru generic T fără constrângere specifică.

Începând cu C# 11 și .NET 7, introducerea Membrilor Statici Virtuali în Interfețe (Static Abstract Members in Interfaces) a deblocat facilitatea Generic Math prin interfața universală INumber<T>.

Algoritm Numeric Generic Universal cu INumber<T>
using System.Numerics;

public class AlgoritmiMatematici
{
    // O singură funcție generică funcționează identic pentru int, double, decimal, float etc.:
    public static T CalculeazaSumaTotala<T>(ReadOnlySpan<T> numere) where T : INumber<T>
    {
        T suma = T.Zero; // Valoarea neutră 0 definită static pe tipul T!

        foreach (T valoare in numere)
        {
            suma += valoare; // Operatorul '+' este validat la compilare prin interfață!
        }

        return suma;
    }
}

public class Program
{
    public static void Main()
    {
        int[] numereIntregi = [10, 20, 30];
        int sumaInt = AlgoritmiMatematici.CalculeazaSumaTotala<int>(numereIntregi);

        double[] numereReale = [1.5, 2.5, 3.5];
        double sumaDouble = AlgoritmiMatematici.CalculeazaSumaTotala<double>(numereReale);

        Console.WriteLine($"Suma int: {sumaInt}, Suma double: {sumaDouble}");
    }
}

Cum Funcționează Sub Capotă?

Interfața INumber<T> declară operatorii matematici ca metode statice abstracte:

public interface IAdditionOperators<TSelf, TOther, TResult>
{
    static abstract TResult operator +(TSelf left, TOther right);
}

La momentul compilării JIT, RyuJIT specializează funcția pentru tipul concret de procesor (monomorfizare nativă), generând instrucțiuni de asamblare identice ca viteză cu codul scris manual pentru fiecare tip în parte.