C#の構造体:値型の定義と活用を徹底解説
C#において、構造体(struct)は値型のデータ型です。関連するさまざまなデータ型のデータを1つの変数で保持するのに役立ちます。構造体を作成するにはstructキーワードを使用します。
構造体はレコードを表現するために使用されます。例えば、図書館の本を管理する場合、以下の属性を追跡したいかもしれません。
- タイトル(Title)
- 著者(Author)
- 主題(Subject)
- 書籍ID(Book ID)
構造体の定義
構造体を定義するにはstructステートメントを使用します。これは、プログラムで複数のメンバーを持つ新しいデータ型を定義します。
Book構造体の宣言例
struct Books {
public string title;
public string author;
public string subject;
public int book_id;
}
構造体の使用例
using System;
struct Books {
public string title;
public string author;
public string subject;
public int book_id;
}
public class TestStructure {
public static void Main(string[] args) {
Books Book1; // Book1をBook型で宣言
Books Book2; // Book2をBook型で宣言
// 書籍1の仕様
Book1.title = "C Programming";
Book1.author = "Nuha Ali";
Book1.subject = "C Programming Tutorial";
Book1.book_id = 6495407;
// 書籍2の仕様
Book2.title = "Telecom Billing";
Book2.author = "Zara Ali";
Book2.subject = "Telecom Billing Tutorial";
Book2.book_id = 6495700;
// 書籍1の情報表示
Console.WriteLine("Book 1 title : {0}", Book1.title);
Console.WriteLine("Book 1 author : {0}", Book1.author);
Console.WriteLine("Book 1 subject : {0}", Book1.subject);
Console.WriteLine("Book 1 book_id : {0}", Book1.book_id);
// 書籍2の情報表示
Console.WriteLine("Book 2 title : {0}", Book2.title);
Console.WriteLine("Book 2 author : {0}", Book2.author);
Console.WriteLine("Book 2 subject : {0}", Book2.subject);
Console.WriteLine("Book 2 book_id : {0}", Book2.book_id);
Console.ReadKey();
}
}
実行結果:
Book 1 title : C Programming
Book 1 author : Nuha Ali
Book 1 subject : C Programming Tutorial
Book 1 book_id : 6495407
Book 2 title : Telecom Billing
Book 2 author : Zara Ali
Book 2 subject : Telecom Billing Tutorial
Book 2 book_id : 6495700
C#構造体の特徴
C#の構造体は、従来のCやC++の構造体とは大きく異なります。主な特徴は以下の通りです。
- メソッド、フィールド、インデクサ、プロパティ、演算子メソッド、イベントを持てる
- コンストラクタを定義できるが、デストラクタは定義できない。デフォルトコンストラクタ(引数なし)は自動的に定義され、変更不可
- クラスとは異なり、構造体は他の構造体やクラスを継承できない
- 構造体を他の構造体やクラスの基底として使用できない
- 1つ以上のインターフェースを実装できる
- 構造体メンバーを
abstract、virtual、protectedとして指定できない new演算子で作成すると適切なコンストラクタが呼ばれる。クラスと異なり、newなしでもインスタンス化可能newを使わない場合、フィールドは未割り当て状態となり、すべてのフィールドが初期化されるまでオブジェクトは使用できない
クラス vs 構造体
| 特徴 | クラス(class) | 構造体(struct) |
|---|---|---|
| 型の種類 | 参照型 | 値型 |
| 継承 | サポート(単一継承) | サポートしない(インターフェース実装のみ) |
| デフォルトコンストラクタ | 定義可能 | 定義不可(自動生成) |
| null許容 | デフォルトで許容 | Nullable<T>でのみ許容 |
| メモリ配置 | ヒープ | スタック(またはインライン) |
| コピー時の挙動 | 参照コピー | 値コピー(ディープコピー) |
メソッドを持つ構造体の例(書き換え版)
using System;
struct Books {
private string title;
private string author;
private string subject;
private int book_id;
public void GetValues(string t, string a, string s, int id) {
title = t;
author = a;
subject = s;
book_id = id;
}
public void Display() {
Console.WriteLine("Title : {0}", title);
Console.WriteLine("Author : {0}", author);
Console.WriteLine("Subject : {0}", subject);
Console.WriteLine("Book_id : {0}", book_id);
}
}
public class TestStructure {
public static void Main(string[] args) {
Books Book1 = new Books();
Books Book2 = new Books();
Book1.GetValues("C Programming", "Nuha Ali", "C Programming Tutorial", 6495407);
Book2.GetValues("Telecom Billing", "Zara Ali", "Telecom Billing Tutorial", 6495700);
Book1.Display();
Book2.Display();
Console.ReadKey();
}
}
readonly struct と ref struct(C# 7.2以降)
readonly struct- 不変な構造体を定義。すべてのフィールドがreadonlyでなければならないref struct- スタックのみに割り当てられる構造体(Span<T>など)。ヒープに逃げないことを保証
readonly structの例
readonly struct Point3D {
public double X { get; }
public double Y { get; }
public double Z { get; }
public Point3D(double x, double y, double z) {
X = x; Y = y; Z = z;
}
public double DistanceFromOrigin => Math.Sqrt(X*X + Y*Y + Z*Z);
}
構造体を使用すべきケース
- 小さなデータ構造(目安:16バイト以下)
- 主にデータを保持し、振る舞いが少ない
- 頻繁に作成/破棄され、ガベージコレクションの負荷を減らしたい
- 値のセマンティクス(コピー時の独立性)が必要
- プリミティブ型のような振る舞いを期待される
ベストプラクティス
- 構造体は
readonlyにして不変性を保つよう心がける - 大きな構造体は避ける(コピーのコストが高いため)
- ボックス化(boxing)を避けるため、インターフェース実装時はジェネリック制約を活用
Equals/GetHashCodeをオーバーライドして値ベースの等価性を正しく実装する- パブリックフィールドではなくプロパティを使用してカプセル化を保つ
C言語
- 次世代磁気ナノ構造「透明マント」でデータストレージを革新
- 2021年 コーディングスキルを飛躍させる厳選17冊のプログラミング本
- 3Dプリント格子構造で部品性能を向上:軽量化・高強度・衝撃吸収を実現
- C++構造体とクラス:組み込み開発者のための実践ガイド
- Nucleus RTOSのセマフォ:ユーティリティサービスとデータ構造
- 書評:『Digitise or Die』——IoT駆動トランスフォーメーションの青写真
- 破壊的テクノロジー時代に人間らしさを保つには
- C言語構造体:複雑なデータを効率的に整理
- C言語typedef:カスタム型名でコードをシンプルに
- C++データ構造:配列、構造体、ポインタで効率的なプログラムを構築
- Javaデータ構造: 従来クラス(Vector/Stack/Hashtable等)とコレクションフレームワーク概要