サーチ…
備考
クラスとは異なり、 struct
は値型であり、 デフォルトではマネージヒープ上ではなくローカルスタック上に作成されます 。つまり、特定のスタックが有効範囲外になると、 struct
割り当てが解除されます。割り当てられていないstruct
のstruct
参照型も、 struct
によって参照されていないとGCが判断すると、掃引されます。
struct
sは継承することができず、継承の基礎となることもできません。暗黙的にシールprotected
います。また、 protected
メンバーを含めることもできません。しかし、クラスが行うように、 struct
はインタフェースを実装することができます。
構造体の宣言
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
インスタンスフィールドは、パラメータ化されたコンストラクタを介して、またはstruct
構築後に個別に設定できます。プライベートメンバーはコンストラクターによってのみ初期化できます。
struct
は、System.ValueTypeから暗黙的に継承される密封型を定義します。構造体は他の型から継承することはできませんが、インタフェースを実装できます。
構造体は割り当て時にコピーされます。つまり、すべてのデータが新しいインスタンスにコピーされ、そのいずれかの変更は他のインスタンスに反映されません。
構造体は
null
でもかまいませんが、null可能な型として使用できnull
。Vector v1 = null; //illegal Vector? v2 = null; //OK Nullable<Vector> v3 = null // OK
構造体は、
new
演算子を使用して、または使用せずにインスタンス化できます。//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;
ただし、イニシャライザを使用するには、
new
演算子を使用する必要があります。Vector v1 = new MyStruct { X=1, Y=2, Z=3 }; // OK Vector v2 { X=1, Y=2, Z=3 }; // illegal
構造体は、いくつかの例外を除いて、クラスが宣言できるすべてを宣言できます。
- 構造体は、パラメータのないコンストラクタを宣言することはできません。
struct
インスタンスフィールドは、パラメータ化されたコンストラクタを介して、またはstruct
構築後に個別に設定できます。プライベートメンバーはコンストラクターによってのみ初期化できます。 - 構造体は暗黙的にシールされているため、メンバーをprotectedとして宣言することはできません。
- 構造体フィールドは、constまたはstaticの場合にのみ初期化できます。
構造体の使用法
コンストラクタで:
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);
コンストラクタなし:
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;
構造体をコンストラクタとともに使用すると、未割り当てフィールドに問題は生じません(各未割り当てフィールドにはNULL値があります)。
クラスとは異なり、構造体を構築する必要はありません。つまり、コンストラクタの1つを呼び出す必要がない場合は、新しいキーワードを使用する必要はありません。構造体は、value-typeでnullにはなれないため、新しいキーワードは必要ありません。
構造体を実装する構造体
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;
}
}
代入時に構造体がコピーされる
シンセ構造体は、すべてのデータが代入時にコピーされる値型であり、新しいコピーを変更しても元のコピーのデータは変更されません。以下のコードスニペットは、 p1
がp2
コピーされ、 p1
加えられた変更が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