C# Language
structs
Sök…
Anmärkningar
Till skillnad från klasser är en struct
en värdetyp och skapas som standard i den lokala stacken och inte på den hanterade högen. Detta innebär att när den specifika stacken går ut ur räckvidden tilldelas struct
. Innehållna referenstyper av avdelade struct
sveps också, när GC bestämmer att de inte längre refereras till av struct
.
struct
kan inte ärva och kan inte utgöra grund för arv, de är implicit förseglade och kan inte heller inkludera protected
medlemmar. En struct
kan emellertid implementera ett gränssnitt, som klasser gör.
Förklarar en struktur
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
kan ställas in via en parametriserad konstruktör eller individuellt efterstruct
.Privata medlemmar kan endast initialiseras av konstruktören.
struct
definierar en förseglad typ som implicit ärver från System.ValueType.Strukturer kan inte ärva från någon annan typ, men de kan implementera gränssnitt.
Strukturer kopieras vid tilldelning, vilket innebär att all data kopieras till den nya instansen och ändringar i en av dem återspeglas inte av den andra.
En struktur kan inte vara
null
, även om den kan användas som en nullable typ:Vector v1 = null; //illegal Vector? v2 = null; //OK Nullable<Vector> v3 = null // OK
Strukturer kan inställas med eller utan att använda den
new
operatören.//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;
Den
new
operatören måste dock användas för att kunna använda en initialisering:Vector v1 = new MyStruct { X=1, Y=2, Z=3 }; // OK Vector v2 { X=1, Y=2, Z=3 }; // illegal
En struktur kan förklara allt som en klass kan förklara, med några få undantag:
- En struktur kan inte förklara en parameterlös konstruktör.
struct
kan ställas in via en parametrerad konstruktör eller individuellt efterstruct
. Privata medlemmar kan endast initialiseras av konstruktören. - En struktur kan inte förklara medlemmar som skyddade, eftersom den implicit är förseglade.
- Strukturfält kan endast initialiseras om de är konst eller statiska.
Strukturanvändning
Med konstruktör:
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);
Utan konstruktör:
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;
Om vi använder en struktur med sin konstruktör kommer vi inte att ha problem med otilldelat fält (varje otilldelat fält har nollvärde).
Till skillnad från klasser behöver en struktur inte konstrueras, dvs det finns inget behov av att använda det nya nyckelordet, såvida du inte behöver ringa en av konstruktörerna. En struktur kräver inte det nya nyckelordet eftersom det är en värdetyp och därför inte kan vara noll.
Struktur implementera gränssnitt
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;
}
}
Strukturer kopieras vid uppdraget
Sinse strukturer är värdetyper all data kopieras vid tilldelning, och varje ändring av den nya kopian ändrar inte data för originalkopian. Kodavsnittet nedan visar att p1
kopieras till p2
och ändringar gjorda på p1
påverkar inte p2
instansen.
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