0Pricing
C# Academy · Lezione

Overload degli operatori aritmetici

Definisca +, -, * per i propri tipi.

Overload degli operatori aritmetici è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.

Perché eseguire l'overload degli operatori aritmetici?

L'overload degli operatori consente ai tipi creati da Lei di usare simboli familiari come +, - e *. Per i tipi simili a valori, come vettori, importi monetari o numeri complessi, questo rende il codice simile alla matematica anziché a una serie di chiamate a metodi.

La sintassi di operator +

Un operatore sottoposto a overload viene dichiarato come metodo public static il cui nome è costituito da operator seguito dal simbolo. Almeno un parametro deve essere del tipo che contiene il metodo.

using System;

public struct Vector2
{
    public int X, Y;
    public Vector2(int x, int y) { X = x; Y = y; }

    public static Vector2 operator +(Vector2 a, Vector2 b)
        => new Vector2(a.X + b.X, a.Y + b.Y);

    public override string ToString() => "(" + X + ", " + Y + ")";
}

public class Program
{
    public static void Main()
    {
        var sum = new Vector2(1, 2) + new Vector2(3, 4);
        Console.WriteLine(sum);
    }
}

Sottrazione e moltiplicazione

È possibile eseguire l'overload di diversi operatori per lo stesso tipo. In questo caso aggiungiamo la sottrazione e la moltiplicazione per scalare al nostro vettore.

using System;

public struct Vector2
{
    public int X, Y;
    public Vector2(int x, int y) { X = x; Y = y; }

    public static Vector2 operator -(Vector2 a, Vector2 b)
        => new Vector2(a.X - b.X, a.Y - b.Y);
    public static Vector2 operator *(Vector2 a, int k)
        => new Vector2(a.X * k, a.Y * k);

    public override string ToString() => "(" + X + ", " + Y + ")";
}

public class Program
{
    public static void Main()
    {
        var v = new Vector2(5, 6) - new Vector2(2, 1);
        Console.WriteLine(v);
        Console.WriteLine(new Vector2(2, 3) * 4);
    }
}

Gli operatori sono sempre static

Gli operatori sottoposti a overload devono essere static. Non agiscono su un this implicito; invece, gli operandi vengono passati come parametri espliciti. Il compilatore associa il simbolo al metodo.

using System;

public struct Money
{
    public decimal Amount;
    public Money(decimal amount) { Amount = amount; }

    public static Money operator +(Money a, Money b)
        => new Money(a.Amount + b.Amount);

    public override string ToString() => "$" + Amount;
}

public class Program
{
    public static void Main()
    {
        var total = new Money(10.5m) + new Money(4.25m);
        Console.WriteLine(total);
    }
}

Operatori unari

Gli operatori unari, come la negazione, accettano un solo operando. Esegua l'overload di operator - con un parametro per supportare espressioni come -v.

using System;

public struct Vector2
{
    public int X, Y;
    public Vector2(int x, int y) { X = x; Y = y; }

    public static Vector2 operator -(Vector2 a)
        => new Vector2(-a.X, -a.Y);

    public override string ToString() => "(" + X + ", " + Y + ")";
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine(-new Vector2(3, -7));
    }
}

Operandi di tipo misto

Un operando può essere di un tipo diverso. Fornendo entrambi gli ordini, consente agli utenti di scrivere l'espressione in modo naturale in entrambi i casi.

using System;

public struct Temperature
{
    public double Celsius;
    public Temperature(double c) { Celsius = c; }

    public static Temperature operator +(Temperature t, double delta)
        => new Temperature(t.Celsius + delta);
    public static Temperature operator +(double delta, Temperature t)
        => new Temperature(t.Celsius + delta);

    public override string ToString() => Celsius + "C";
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine(new Temperature(20) + 5);
        Console.WriteLine(5 + new Temperature(20));
    }
}

Restituire nuovi valori

Gli operatori aritmetici non dovrebbero modificare i propri operandi. Calcolano e restituiscono un valore nuovo, lasciando invariati gli originali, proprio come fa int.

using System;

public struct Vector2
{
    public int X, Y;
    public Vector2(int x, int y) { X = x; Y = y; }
    public static Vector2 operator +(Vector2 a, Vector2 b)
        => new Vector2(a.X + b.X, a.Y + b.Y);
    public override string ToString() => "(" + X + ", " + Y + ")";
}

public class Program
{
    public static void Main()
    {
        var a = new Vector2(1, 1);
        var b = new Vector2(2, 2);
        var c = a + b;
        Console.WriteLine("a unchanged: " + a);
        Console.WriteLine("result: " + c);
    }
}

Combinare le operazioni aritmetiche

Poiché ogni operatore restituisce lo stesso tipo, le espressioni possono essere combinate naturalmente e rispettano la normale precedenza e associatività.

using System;

public struct Vector2
{
    public int X, Y;
    public Vector2(int x, int y) { X = x; Y = y; }
    public static Vector2 operator +(Vector2 a, Vector2 b) => new Vector2(a.X + b.X, a.Y + b.Y);
    public static Vector2 operator *(Vector2 a, int k) => new Vector2(a.X * k, a.Y * k);
    public override string ToString() => "(" + X + ", " + Y + ")";
}

public class Program
{
    public static void Main()
    {
        var result = new Vector2(1, 1) + new Vector2(2, 2) * 3;
        Console.WriteLine(result);
    }
}

Operatori nelle classi

L'overload degli operatori funziona anche nelle classi, non solo nelle struct. Presti attenzione a null: un operando di tipo classe potrebbe essere null, quindi aggiunga un controllo se necessario.

using System;

public class Complex
{
    public double Re, Im;
    public Complex(double re, double im) { Re = re; Im = im; }
    public static Complex operator +(Complex a, Complex b)
        => new Complex(a.Re + b.Re, a.Im + b.Im);
    public override string ToString() => Re + " + " + Im + "i";
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine(new Complex(1, 2) + new Complex(3, 4));
    }
}

Un tipo numerico completo

Ecco un piccolo tipo per rappresentare frazioni, con il supporto all'addizione. Mostra come l'overload trasformi un tipo di dominio in qualcosa che si comporta come un numero predefinito.

using System;

public struct Fraction
{
    public int Num, Den;
    public Fraction(int num, int den) { Num = num; Den = den; }

    public static Fraction operator +(Fraction a, Fraction b)
        => new Fraction(a.Num * b.Den + b.Num * a.Den, a.Den * b.Den);

    public override string ToString() => Num + "/" + Den;
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine(new Fraction(1, 2) + new Fraction(1, 3));
    }
}

Provi personalmente

Aggiunga a una struct simile a un importo monetario l'addizione e la moltiplicazione per scalare, quindi costruisca un'espressione che sembri una normale operazione aritmetica.

using System;

public struct Money
{
    public decimal Amount;
    public Money(decimal a) { Amount = a; }
    public static Money operator +(Money a, Money b) => new Money(a.Amount + b.Amount);
    public static Money operator *(Money a, int qty) => new Money(a.Amount * qty);
    public override string ToString() => "$" + Amount;
}

public class Program
{
    public static void Main()
    {
        var price = new Money(4.50m);
        var total = price * 3 + new Money(2.00m);
        Console.WriteLine(total);
    }
}

Verifica rapida

Ricordi la firma di un operatore sottoposto a overload.

Riepilogo

L'overload degli operatori aritmetici rende i tipi simili a valori leggibili come espressioni matematiche.

  • Li dichiari public static con la parola chiave operator.
  • Almeno un parametro deve essere del tipo che contiene il metodo.
  • Restituisca un valore nuovo; non modifichi mai gli operandi.
  • Fornisca entrambi gli ordini degli operandi per l'aritmetica tra tipi diversi.

Domande Frequenti

La lezione «Overload degli operatori aritmetici» è gratuita?

Sì — il testo completo di «Overload degli operatori aritmetici» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.

Cosa imparerò in «Overload degli operatori aritmetici»?

Definisca +, -, * per i propri tipi. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C# Academy?

Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Overload degli operatori aritmetici»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C# Academy?

Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Overload degli operatori aritmetici
  2. Overload degli operatori di confronto
  3. Conversioni definite dall'utente
  4. Best practice per l'overload degli operatori
← Torna a C# Academy