値型と参照型の分類
定義済み組み込み型
| 区分 | 含まれる型 |
|---|---|
| 値型(基本数値 / 真偽値 / 文字) | 符号付き整数:sbyte、short、int、long符号なし整数: byte、ushort、uint、ulong浮動小数 / 高精度: float、double、decimal真偽値: bool文字: char |
| 参照型(組み込み参照型) | object(すべての型の基底クラス)、string、dynamic |
ユーザー定義型
| 区分 | 型 |
|---|---|
| 値型 | struct(構造体)、enum(列挙型) |
| 参照型 | class、interface、delegate、array(配列) |
前回の講義で説明した通り、参照型のデータは必ずヒープ上に配置されます。一方、値型のデータはヒープに置かれる場合もあれば、スタックに置かれる場合もあります。
参照型の参照情報自体は、ヒープまたはスタックのいずれかに配置されます。
値型変数や参照型の参照部分がヒープとスタックどちらに配置されるかは、それが型のメンバー変数なのか、関数内のローカル変数なのかによって決まります。
4種類の変数
| 変数種別 | 定義と役割 |
|---|---|
| ローカル変数 Local variable | メソッド内の一時的なデータで型メンバーではない; スタック上に確保 自動初期化されない |
| フィールド Field | クラス / 構造体に紐付くデータで型メンバー; クラスフィールドはヒープ上 構造体フィールドは構造体に従って配置; 自動初期化される |
| パラメータ Parameter | メソッド引数用の一時変数、型メンバーではない; スタック上に確保 自動初期化されない |
| 配列要素 Array element | 配列内の個々のデータ; すべてヒープ上に配置 自動初期化される |
自動初期化とは、プログラマーが明示的に初期値を与えなくても、コンパイラが自動で既定値を設定する仕組みのことです。
簡単にまとめると
| 変数種別 | 配置場所 | 自動初期化 |
|---|---|---|
| ローカル変数 | スタック / スタック+ヒープ | しない |
| クラスフィールド | ヒープ | する |
| 構造体フィールド | スタック / ヒープ | する |
| メソッドパラメータ | スタック | しない |
| 配列要素 | ヒープ | する |

変数宣言
書式:型 変数名;
int var2;Code language: C# (cs)
このコードは変数を宣言しており、主に2つの処理が行われます。
- コンパイラに対し、var2 が int 型の変数であることを通知する。
- コンパイラがメモリ領域を確保する。配置先がヒープかスタックかは、ローカル変数・引数・フィールドなどの状況により変わります。

変数イニシャライザ(Initializer)
文法:型 変数名 = 初期値;
例:int var2 = 17;
イニシャライザはコンパイラの機能で変数の初期化を支援します。変数によっては開発者がコード上で明示的に初期化する必要があるものと、イニシャライザに任せてよいものに分かれます。
初期化されていないローカル変数は値が不定となり、コンパイルエラーが発生し直接利用できません;
フィールドや配列要素など自動初期化対象の変数には既定値が割り当てられます:数値型は0、参照型はnull。
サンプルコードを見てみましょう:
class Program
{
static void Main(string[] args)
{
int times = 100;
Person person = new Person();
}
}
class Person
{
public int age;
}
Code language: C# (cs)
この簡単な例では、Main関数内に値型変数 times と参照型変数 person を定義しています。参照型にはフィールド age が存在します。
age には初期値を設定しておらず、times には開発者が初期値を指定しています。
このコードは正常にコンパイルできます。

times の初期値 100 を削除し下記のように記述すると

変数に赤い波線が表示されコンパイルが通らなくなります。
無理にコンパイルを実行するとエラーが出力されます

エラーリストウィンドウに詳細なエラー情報が表示されます

注意:コード内で times 変数を使用した場合のみエラーが発生します。一度も参照しない場合はエラーが出ずコンパイル可能です。
class Program
{
static void Main(string[] args)
{
int times;
Person person = new Person();
}
}
Code language: C# (cs)
一方、クラス内のフィールド、例えば下記 Person の age は初期値を指定しなくてもコンパイル・実行可能です。
class Program
{
static void Main(string[] args)
{
int times = 100;
Console.WriteLine(times);
Person person = new Person();
Console.WriteLine(person.age);
}
}
class Person
{
public int age;
}
Code language: C# (cs)

実行結果は0と出力されます。age はクラスのメンバーフィールドなので初期値を記述しなくてもイニシャライザにより既定値が設定されます。int型の既定値は0で、型ごとに既定値は異なります。
1行で複数変数を宣言
- 同一行には同じ型の変数のみ宣言可能;
- 変数名をコンマで区切り、初期化済み・未初期化変数を混在させられる;
- 1行に複数の型を混ぜて記述することは禁止。
// 正常
int var3 = 7, var4, var5 = 3;
double var6, var7 = 6.52;
// 不正!int と float を混在
int var8, float var9;
Code language: JavaScript (javascript)
変数の値を参照する
変数名を記述するだけでメモリ上の値を読み取れます:
Console.WriteLine("{0}", var2);Code language: JavaScript (javascript)

変数