.NET開発者のためのブログメディア

C#の構造体を基礎から解説。配列との組み合わせや初期化の方法
C#はオブジェクト指向の開発言語です。オブジェクト指向の言語にはクラスという概念が存在します。クラスの理解なしに、C#を使ったコーディングはできないといえるでしょう。さらに、このクラスに似た概念のひとつに構造体が存在します。クラスと構造体の違いなどを含めて、ここでは構造体の基本的な使い方を解説していきます。
- SE
- 構造体とクラスはどう違うのですか?自分で新しくプログラマソースを作成する場合には、どうしてもクラスで作成してしまいます。
- PM
- ほとんどの場合はクラスで大丈夫ですよ!ですが、クラスはヒープ領域、構造体はスタック領域に展開されるなど、C#プログラマーとして知っておくべき事柄はありますので、ここで一緒に確認していきましょう。
実行環境
・Visual Studio Community 2017
目次
C#の構造体とは?クラスと構造体の違い
構造体とクラスは非常によく似ています。多くの場合はクラスで作成することになるかと思いますが、ときには構造体で定義するべき場面もあります。まずは両者の違いを簡単に理解しておきましょう。
■構造体とクラスの違い早見表
構造体 | クラス | |
---|---|---|
オブジェクトの型 | 値型 | 参照型 |
継承 | 不可 | 可能 |
デフォルトコンストラクタの定義 | 不可 | 可能 |
デストラクタの定義 | 不可 | 可能 |
クラスは参照型ですが、構造体は値型です。参照型であるクラスは、ヒープ領域に割り当てられ、メモリ管理はガベージコレクションで管理されています。それに対して、値型である構造体はスタック領域に割り当てられます。スコープの外に出たときにメモリは自動で解放されますので、メモリ管理等は参照型のクラスに比べて楽だといえます。
型のインスタンスが小さく、有効期間が短い場合には、クラスではなく構造体を使用するのも選択肢のひとつです。
また、構造体は値型であるため、初期値はnullではなく、構造体の各フィールドはそれぞれのデフォルト値で初期化した値となります。そのため構造体を要素とする配列を初期化した時点で、配列の各要素には構造体の初期値が代入されているということになります。
構造体の定義と初期化の方法
それでは、構造体を使ってコーディングを行うための基本的な事柄である、「構造体の定義と初期化」を行う方法を解説していきます。
構造体を使うためには、あるキーワードが必要となります。それが「struct」です。これは、クラスの宣言時のclassキーワードがstructキーワードに変わっただけともいえます。
そして、構造体の変数は値型であるため、実体はスタック領域にあることは忘れないようにしましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
using System; using System.Windows.Forms; namespace WindowsFormsApp29 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Structure st = new Structure(2, 3); System.Diagnostics.Debug.Print("{0}", st.test1); System.Diagnostics.Debug.Print("{0}", st.test2); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WindowsFormsApp29 { struct Structure { public int test1; public int test2; // 引数ありのコンストラクタで初期化 public Structure(int test1, int test2) { // 各フィールドに初期値を設定する this.test1 = test1; this.test2 = test2; } } } |
実行結果
構造体と配列の使用方法
次に、構造体と配列の使用方法についても簡単に解説していきます。
配列をフィールドに持つ構造体では、初期化によって配列フィールドに初期値を設定することができません。また、初期化されていないフィールドを参照しようとするとエラーとなりますので、注意が必要です。
構造体内にある配列フィールドを参照する場合は、事前に配列を確保して代入しておく必要があります。または、引数ありのコンストラクタを用意し、構造体を使用する場合には、それを使って初期化する方法もあります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
using System; using System.Windows.Forms; namespace WindowsFormsApp29 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Structure st; st.Data = new string[5]; st.Data[0] = "東京"; st.Data[1] = "大阪"; st.Data[2] = "福岡"; st.Data[3] = "名古屋"; st.Data[4] = "札幌"; foreach (var i in st.Data) { System.Diagnostics.Debug.Print("{0}", i); } } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WindowsFormsApp29 { struct Structure { // 配列を定義します public string[] Data; } } |
実行結果
- SE
- 構造体とクラスの違いについて理解できました。ヒープ領域とかスタック領域などメモリの領域についての勉強が必要そうですね。構造体を使う場面があれば、積極的に活用していきます。
- PM
- ワンランク上のプログラマーを目指すのならば、違いは明確にしておきましょう。構造体とクラスを何となく使うのではなく、使い分ける理由もきちんと説明できると良いですよ!
構造体とクラスの違いは明確にしておきましょう
今回解説したように、構造体とクラスはほとんど似た使い方をします。大きな違いはヒープ領域に確保するのか、スタック領域に確保するのかにあります。
この違いは重要で、参照型や値型などの知識は、C#のプログラミングを行うためには知っておくべき事柄です。知らない方はこの機会に改めてメモリの領域や管理についての理解を深めておくことをおすすめします。