C# Language
Structs
Ricerca…
Osservazioni
A differenza delle classi, una struct
è un tipo di valore, e viene creata sullo stack locale e non sull'heap gestito, per impostazione predefinita . Ciò significa che una volta che lo stack specifico esce dall'ambito, la struct
viene struct
. Anche i tipi di riferimento struct
nenti alle struct
vengono spazzati, una volta che il GC determina che non sono più riferiti dalla struct
.
struct
s non può ereditare e non può essere base per ereditarietà, sono implicitamente sigillate e non possono includere membri protected
. Tuttavia, una struct
può implementare un'interfaccia, come fanno le classi.
Dichiarazione di una struttura
public struct Vector
{
public int X;
public int Y;
public int Z;
}
public struct Point
{
public decimal x, y;
public Point(decimal pointX, decimal pointY)
{
x = pointX;
y = pointY;
}
}
struct
campi istanzastruct
possono essere impostati tramite un costruttore parametrizzato o singolarmente dopo la costruzione distruct
.I membri privati possono essere inizializzati solo dal costruttore.
struct
definisce un tipo sealed che eredita implicitamente da System.ValueType.Le strutture non possono ereditare da nessun altro tipo, ma possono implementare interfacce.
Le strutture vengono copiate sull'assegnazione, ovvero tutti i dati vengono copiati nella nuova istanza e le modifiche a una di esse non vengono riflesse dall'altra.
Una struct non può essere
null
, sebbene possa essere usato come un tipo nullable:Vector v1 = null; //illegal Vector? v2 = null; //OK Nullable<Vector> v3 = null // OK
Le strutture possono essere istanziate con o senza l'utilizzo del
new
operatore.//Both of these are acceptable Vector v1 = new Vector(); v1.X = 1; v1.Y = 2; v1.Z = 3; Vector v2; v2.X = 1; v2.Y = 2; v2.Z = 3;
Tuttavia, è necessario utilizzare il
new
operatore per utilizzare un inizializzatore:Vector v1 = new MyStruct { X=1, Y=2, Z=3 }; // OK Vector v2 { X=1, Y=2, Z=3 }; // illegal
Una struct può dichiarare tutto ciò che una classe può dichiarare, con alcune eccezioni:
- Una struct non può dichiarare un costruttore senza parametri.
struct
campi istanzastruct
possono essere impostati tramite un costruttore parametrizzato o singolarmente dopo la costruzione distruct
. I membri privati possono essere inizializzati solo dal costruttore. - Una struct non può dichiarare i membri come protetti, dal momento che è implicitamente sigillato.
- I campi Struct possono essere inizializzati solo se costanti o statici.
Struct utilizzo
Con il costruttore:
Vector v1 = new Vector();
v1.X = 1;
v1.Y = 2;
v1.Z = 3;
Console.WriteLine("X = {0}, Y = {1}, Z = {2}",v1.X,v1.Y,v1.Z);
// Output X=1,Y=2,Z=3
Vector v1 = new Vector();
//v1.X is not assigned
v1.Y = 2;
v1.Z = 3;
Console.WriteLine("X = {0}, Y = {1}, Z = {2}",v1.X,v1.Y,v1.Z);
// Output X=0,Y=2,Z=3
Point point1 = new Point();
point1.x = 0.5;
point1.y = 0.6;
Point point2 = new Point(0.5, 0.6);
Senza costruttore:
Vector v1;
v1.Y = 2;
v1.Z = 3;
Console.WriteLine("X = {0}, Y = {1}, Z = {2}",v1.X,v1.Y,v1.Z);
//Output ERROR "Use of possibly unassigned field 'X'
Vector v1;
v1.X = 1;
v1.Y = 2;
v1.Z = 3;
Console.WriteLine("X = {0}, Y = {1}, Z = {2}",v1.X,v1.Y,v1.Z);
// Output X=1,Y=2,Z=3
Point point3;
point3.x = 0.5;
point3.y = 0.6;
Se usiamo una struct con il suo costruttore, non avremo problemi con il campo non assegnato (ogni campo non assegnato ha valore null).
A differenza delle classi, non è necessario costruire una struttura, ovvero non è necessario utilizzare la nuova parola chiave, a meno che non sia necessario chiamare uno dei costruttori. Una struct non richiede la nuova parola chiave perché è un tipo di valore e quindi non può essere nullo.
Struct interfaccia di implementazione
public interface IShape
{
decimal Area();
}
public struct Rectangle : IShape
{
public decimal Length { get; set; }
public decimal Width { get; set; }
public decimal Area()
{
return Length * Width;
}
}
Le strutture sono copiate sul compito
Le strutture sinse sono tipi di valore, tutti i dati vengono copiati durante l'assegnazione e qualsiasi modifica alla nuova copia non modifica i dati per la copia originale. Il frammento di codice seguente mostra che p1
è copiato in p2
e le modifiche apportate su p1
non influenzano l'istanza di p2
.
var p1 = new Point {
x = 1,
y = 2
};
Console.WriteLine($"{p1.x} {p1.y}"); // 1 2
var p2 = p1;
Console.WriteLine($"{p2.x} {p2.y}"); // Same output: 1 2
p1.x = 3;
Console.WriteLine($"{p1.x} {p1.y}"); // 3 2
Console.WriteLine($"{p2.x} {p2.y}"); // p2 remain the same: 1 2