1. Introduzione
Struct — è un tipo di dato speciale in C# che ti permette di unire diversi valori (anche di tipi diversi) in una sola “scatoletta”. È come un piccolo set LEGO: metti insieme i pezzi e alla fine hai un oggetto comodo e compatto.
Le struct sono simili alle class, ma hanno delle particolarità, e si usano per casi più “semplici”, quando non serve tutta la potenza e la “pesantezza” delle class.
Sintassi
struct Point
{
public int X;
public int Y;
}
In questo esempio abbiamo descritto una struct per un punto sul piano con le coordinate X e Y.
Dove si usano le struct?
Di solito le struct si usano per oggetti piccoli e semplici, che devono essere molto leggeri e “solo dati”.
In C# alcuni tipi standard sono struct:
- int, double, bool, DateTime, TimeSpan, decimal, Guid
- e anche, per esempio, ConsoleKeyInfo o Point (nelle librerie grafiche)
Differenze tra struct e class
| Criterio | Struct | Class |
|---|---|---|
| Parola chiave | |
|
| Tipo di memorizzazione | Value Type | Reference Type |
| Memorizzato in | Stack (zona di memoria) | Heap (zona di memoria) |
| Passaggio al metodo | Per valore (copia) | Per riferimento |
| Ereditarietà | No (tranne le interfacce) | Sì |
| Può essere null | No (solo Nullable) | Sì |
| Di default | Inizializzazione implicita di tutti i campi a zero | Solo tramite costruttore |
2. Dichiarazione e uso delle struct
Puoi dichiarare una struct dentro o fuori da una class:
struct Rectangle
{
public int Width;
public int Height;
}
Creazione e uso:
Rectangle r;
r.Width = 10;
r.Height = 5;
Console.WriteLine($"Area: {r.Width * r.Height}");
Puoi anche usare un costruttore:
struct Point
{
public int X;
public int Y;
// Costruttore
public Point(int x, int y)
{
X = x;
Y = y;
}
}
var p = new Point(3, 7);
Console.WriteLine($"Punto: ({p.X}, {p.Y})");
Quando conviene usare una struct?
- Per piccoli “pacchetti” di dati (tipo coordinate, colore, intervallo, data e ora).
- Quando conta la compattezza e la performance (tipo milioni di punti in un array).
- Quando l’oggetto deve comportarsi come un valore unico (copy-paste — funziona proprio la copia!).
Non usare una struct se l’oggetto:
- Può essere grande (tanti campi).
- Deve stare in una gerarchia di ereditarietà.
- Deve cambiare spesso tramite riferimento.
3. Particolarità e “trappole” delle struct
Copia
Point p1 = new Point(1, 2);
Point p2 = p1; // si crea una COPIA!
p2.X = 100;
Console.WriteLine(p1.X); // 1 — non è cambiato!
Console.WriteLine(p2.X); // 100
Valori impliciti di default
Point p; // i campi X e Y = 0, anche se non li hai assegnati!
Può essere Nullable
Per poter assegnare null, devi usare la sintassi nullable — metti un punto interrogativo dopo il nome del tipo. Così puoi assegnare null alla variabile.
Point? p = null;
if (p == null)
Console.WriteLine("Nessun punto");
4. Struct con proprietà automatiche e metodi
Le struct possono avere metodi, proprietà, eventi e anche membri statici.
public struct Range
{
public int Start { get; set; }
public int End { get; set; }
public int Length => End - Start;
public override string ToString() => $"[{Start}..{End}]";
}
Esempio: struct per numeri complessi
Struct per numeri complessi con metodo e override di ToString()
struct Complex
{
public double Re;
public double Im;
public Complex(double re, double im)
{
Re = re;
Im = im;
}
public double Abs() => Math.Sqrt(Re * Re + Im * Im);
public override string ToString() => $"{Re} + {Im}i";
}
var z = new Complex(1, 2);
Console.WriteLine(z); // 1 + 2i
Console.WriteLine(z.Abs()); // 2.236...
GO TO FULL VERSION