.NETにおけるstructとclassの違いを日本語で解説(例付き)
.NETにおけるstructとclassの違いを日本語で解説
structとclassは、.NETフレームワークにおける2つの基本的なデータ型です。どちらもオブジェクト指向プログラミングの概念に基づいていますが、いくつかの重要な違いがあります。
共通点
- 両者はメンバー(フィールドやメソッド)を持つことができます。
- 両者は継承をサポートします。
違い
メモリ管理
- struct: 値型であり、スタックに割り当てられます。値そのものがコピーされます。
- class: 参照型であり、ヒープに割り当てられます。参照がコピーされます。
継承
- struct: 継承できますが、必ず
System.ValueType
から継承しなければなりません。 - class: 他のクラスから継承できます。
デフォルトコンストラクタ
- struct: デフォルトコンストラクタが暗黙的に定義されます。
- class: デフォルトコンストラクタは明示的に定義するか、自動実装プロパティを使用する必要があります。
null許容
- struct: 値型なので、
null
を割り当てることができません。
パフォーマンス
- struct: 一般的に、値型であるため、参照型の操作よりもパフォーマンスが優れています。ただし、頻繁にコピーされる場合はパフォーマンスが低下することがあります。
- class: 参照型であるため、頻繁なコピーはパフォーマンスに影響を与えません。
いつどちらを使うべきか
- struct: 小さなデータ構造で、頻繁にコピーされる場合。
- class: より複雑なデータ構造で、大きなデータや参照型が必要な場合。
例:
// struct
struct Point
{
public int X { get; set; }
public int Y { get; set; }
}
// class
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
この例では、Point
は小さなデータ構造であり、頻繁にコピーされる可能性があるため、struct
として定義されています。一方、Person
はより複雑なデータ構造であり、class
として定義されています。
// struct
struct Point
{
public int X { get; set; }
public int Y { get; set; }
}
// class
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
// 使用例
Point p1 = new Point { X = 10, Y = 20 };
Point p2 = p1; // p1の値がコピーされる
p2.X = 30;
Console.WriteLine(p1.X); // 出力: 10
Person person1 = new Person { Name = "Alice", Age = 30 };
Person person2 = person1; // person1への参照がコピーされる
person2.Age = 40;
Console.WriteLine(person1.Age); // 出力: 40
この例では、Point
は値型なので、p1
の値がコピーされて p2
に割り当てられます。そのため、p2
の値を変更しても p1
の値は影響を受けません。一方、Person
は参照型なので、person1
への参照がコピーされて person2
に割り当てられます。そのため、person2
の値を変更すると person1
の値も変更されます。
struct Point3D : Point
{
public int Z { get; set; }
}
class Employee : Person
{
public string Department { get; set; }
}
この例では、Point3D
は Point
から継承していますが、Employee
は Person
から継承しています。
struct Point
{
// デフォルトコンストラクタが暗黙的に定義される
}
class Person
{
public string Name { get; set; }
public int Age { get; set; }
// デフォルトコンストラクタを明示的に定義
public Person()
{
// コンストラクタの処理
}
}
Point p = new Point(); // nullを割り当てることはできない
Person person = null; // nullを割り当てることができる
Record
- C# 9から導入された新しいデータ型です。
- structと似ていますが、自動生成されたプロパティ、イミュータビリティ、および効率的な実装が特徴です。
- structの代替として使用できます。
record Point(int X, int Y);
Tuple
- 匿名型の集合です。
- structの代替として使用できますが、プロパティ名を持たないため、読みやすさが低下する可能性があります。
var point = (X: 10, Y: 20);
Dictionary
- キーと値のペアを格納するコレクションです。
- structの代替として使用できますが、キーと値のペアのアクセスが遅くなる可能性があります。
var point = new Dictionary<string, int>
{
{ "X", 10 },
{ "Y", 20 }
};
Custom Data Types
- 独自のデータ型を定義することで、特定のニーズに合わせた機能を提供することができます。
- structとclassの代替として使用できますが、実装が複雑になる可能性があります。
class MyPoint
{
public int X { get; set; }
public int Y { get; set; }
public MyPoint(int x, int y)
{
X = x;
Y = y;
}
}
どの手法を使うべきか
- Record: structの代替として、シンプルなデータ構造を定義したい場合に最適です。
- Tuple: structの代替として、プロパティ名が必要ない場合に使用できますが、読みやすさに注意が必要です。
- Dictionary: structの代替として、キーと値のペアを格納したい場合に使用できますが、アクセス性能に注意が必要です。
- Custom Data Types: 特定のニーズに合わせて、独自のデータ型を定義したい場合に使用できます。
.net class struct