C# Language
Struktury
Szukaj…
Uwagi
W przeciwieństwie do klas, struct
jest typem wartości i domyślnie jest tworzony na stosie lokalnym, a nie na sterowanej stercie. Oznacza to, że gdy określony stos wykracza poza zakres, struct
zostaje anulowana. Zawarte typy referencyjne nieprzydzielonych struct
są również usuwane, gdy GC stwierdzi, że nie są już przywoływane przez struct
.
struct
nie mogą dziedziczyć i nie mogą być podstawami do dziedziczenia, są domyślnie zapieczętowane, a także nie mogą obejmować członków protected
. Jednak struct
może implementować interfejs, podobnie jak klasy.
Deklarowanie struktury
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;
}
}
pola instancji
struct
można ustawić za pomocą sparametryzowanego konstruktora lub indywidualnie po konstrukcjistruct
.Członkowie prywatni mogą być inicjowani tylko przez konstruktora.
struct
definiuje typ zapieczętowany, który domyślnie dziedziczy po System.ValueType.Struktury nie mogą dziedziczyć po żadnym innym typie, ale mogą implementować interfejsy.
Struktury są kopiowane przy przypisaniu, co oznacza, że wszystkie dane są kopiowane do nowej instancji, a zmiany w jednej z nich nie są odzwierciedlane przez drugą.
Struktura nie może mieć
null
, chociaż może być używana jako typnull
:Vector v1 = null; //illegal Vector? v2 = null; //OK Nullable<Vector> v3 = null // OK
Struktury mogą być tworzone za pomocą
new
operatora lub bez niego.//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;
Jednak aby użyć inicjatora, należy użyć
new
operatora:Vector v1 = new MyStruct { X=1, Y=2, Z=3 }; // OK Vector v2 { X=1, Y=2, Z=3 }; // illegal
Struktura może deklarować wszystko, co klasa może deklarować, z kilkoma wyjątkami:
- Struktur nie może zadeklarować konstruktora bez parametrów. Pola instancji
struct
można ustawić za pomocą sparametryzowanego konstruktora lub indywidualnie po konstrukcjistruct
. Członkowie prywatni mogą być inicjowani tylko przez konstruktora. - Struktura nie może zadeklarować członków jako chronionych, ponieważ jest niejawnie zapieczętowana.
- Pola strukturalne można inicjalizować tylko wtedy, gdy są stałe lub statyczne.
Użycie struktury
Z konstruktorem:
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);
Bez konstruktora:
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;
Jeśli użyjemy struktury z jej konstruktorem, nie będziemy mieć problemów z nieprzypisanym polem (każde nieprzypisane pole ma wartość null).
W przeciwieństwie do klas, struct nie musi być konstruowany, tzn. Nie trzeba używać nowego słowa kluczowego, chyba że trzeba wywołać jeden z konstruktorów. Struktura nie wymaga nowego słowa kluczowego, ponieważ jest typem wartości, a zatem nie może mieć wartości NULL.
Interfejs implementujący Struct
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;
}
}
Struktury są kopiowane przy przypisaniu
Struktury Sinse są typami wartości, wszystkie dane są kopiowane w momencie przypisania, a wszelkie modyfikacje nowej kopii nie zmieniają danych oryginalnej kopii. Poniższy fragment kodu pokazuje, że p1
jest kopiowany do p2
a zmiany dokonane w p1
nie wpływają na instancję 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