基本データ型(C#)
『C#』で扱う基本データ型(プリミティブ型)の一覧と、値型・参照型の違い、var による型推論、暗黙的な型変換と明示的なキャストを解説します。型を正しく選ぶことでメモリ効率の改善やバグの防止につながります。
基本データ型の一覧
| 型名 | エイリアス | サイズ | 値の範囲・説明 |
|---|---|---|---|
System.Int32 | int | 32ビット | -2,147,483,648 〜 2,147,483,647。整数の最も基本的な型です。 |
System.Int64 | long | 64ビット | -9,223,372,036,854,775,808 〜 9,223,372,036,854,775,807。int に収まらない大きな整数に使います。 |
System.Double | double | 64ビット | 約 ±1.7×10³⁰⁸。倍精度浮動小数点数。浮動小数点数のデフォルト型です。 |
System.Single | float | 32ビット | 約 ±3.4×10³⁸。単精度浮動小数点数。Unity などで多用します。リテラルには f サフィックスが必要です。 |
System.Decimal | decimal | 128ビット | 28〜29桁の10進精度。金融計算など誤差が許されない場面に使います。リテラルには m サフィックスが必要です。 |
System.Char | char | 16ビット | Unicode 文字1文字(U+0000 〜 U+FFFF)。シングルクォートで囲みます。 |
System.Boolean | bool | 1ビット相当 | true または false のみ。条件式に使えるのはこの型だけです。 |
System.String | string | 可変長 | Unicode 文字列。参照型ですが不変(immutable)で、値型のように直感的に扱えます。 |
値型と参照型の違い
| 値型(Value Type) | 参照型(Reference Type) | |
|---|---|---|
| 格納場所 | スタック(または構造体のフィールド内) | ヒープ(変数はヒープへの参照を保持) |
| 代入の挙動 | 値そのものがコピーされます。 | 参照(アドレス)がコピーされます。 |
| デフォルト値 | 0 / false / '\0' など型ごとに定まります。 | null(参照先なし)です。 |
| 代表的な型 | int / long / double / float / decimal / char / bool / struct | string / 配列 / クラス / object |
string は参照型に分類されますが、文字列は不変(immutable)なので、変数に別の文字列を代入すると元の文字列オブジェクトには影響がありません。このため値型のように直感的に扱うことができます。
var による型推論
var を使うと、右辺の値からコンパイラが自動的に型を推論します。あくまでコンパイル時に型が確定する静的型付けであり、実行時に型が変わるわけではありません。型名が長くなりがちな場合に可読性が上がりますが、右辺から型が自明でない場合は明示的な型名を書いた方が読みやすくなります。
// var を使った型推論の例です。 var power = 9000; // int として推論されます。 var name = "孫悟空"; // string として推論されます。 var ratio = 1.5; // double として推論されます。 var isAlive = true; // bool として推論されます。 // 右辺が明示的でない場合は型名を書く方がわかりやすいです。 int hp = 0; string title = "超サイヤ人";
サンプルコード
BasicTypes.cs
各基本型の宣言と出力を確認するサンプルです。
using System;
class BasicTypes {
static void Main() {
// --- int: 通常の整数値です ---
int power = 9000; // 孫悟空の戦闘力(int 範囲内に収まります)。
int maxPower = int.MaxValue; // int の最大値を確認します。
Console.WriteLine("power = " + power);
Console.WriteLine("int.Max = " + maxPower); // 2147483647 が出力されます。
// --- long: int に収まらない大きな整数です ---
// フリーザの戦闘力を誇張して long で表現します(リテラルに L サフィックスを付けます)。
long frieza = 530_000_000L; // アンダースコアで桁を区切ると読みやすくなります。
Console.WriteLine("フリーザの戦闘力 = " + frieza);
// --- double: 倍精度浮動小数点数です ---
double multiplier = 1.5; // 超サイヤ人の倍率(仮定値)。
double result = power * multiplier;
Console.WriteLine("超サイヤ人パワー = " + result); // 13500 が出力されます。
// --- float: 単精度浮動小数点数です(リテラルに f が必要)---
float speed = 9.8f; // 移動速度(float)。
Console.WriteLine("speed = " + speed);
// --- decimal: 高精度な10進数です(リテラルに m が必要)---
// お金の計算など誤差を許容できない場面に使います。
decimal price = 1980.50m; // 道着の値段(税抜き)。
decimal taxRate = 0.10m;
decimal taxPrice = price * (1 + taxRate); // 税込み価格を計算します。
Console.WriteLine("税込み価格 = " + taxPrice + " 円"); // 2178.5500 が出力されます。
// --- char: 1文字です(シングルクォートで囲みます)---
char initial = '悟'; // 孫悟空の名前の1文字目。
Console.WriteLine("initial = " + initial);
Console.WriteLine("charCode = " + (int)initial); // Unicode コードポイントを確認します。
// --- bool: true / false のみです ---
bool isSaiyan = true;
bool hasTail = false;
Console.WriteLine("サイヤ人: " + isSaiyan + ", 尻尾あり: " + hasTail);
// --- string: 文字列です(参照型ですが不変)---
string hero = "孫悟空";
string transformed = hero + "(超サイヤ人)"; // 連結すると新しい string が生成されます。
Console.WriteLine(transformed); // 元の hero は変わりません。
Console.WriteLine("hero = " + hero); // "孫悟空" のまま変わっていません。
}
}
コンパイルして実行すると次のようになります。
dotnet script BasicTypes.cs power = 9000 int.Max = 2147483647 フリーザの戦闘力 = 530000000 超サイヤ人パワー = 13500 speed = 9.8 税込み価格 = 2178.5500 円 initial = 悟 charCode = 24735 サイヤ人: True, 尻尾あり: False 孫悟空(超サイヤ人) hero = 孫悟空
TypeConversion.cs
暗黙的な型変換・明示的なキャスト・Convert クラスを使った変換のサンプルです。
using System;
class TypeConversion {
static void Main() {
// ===== 暗黙的な型変換 =====
// 小さい型から大きい型への変換は自動で行われます(データが失われません)。
int intPower = 9000;
long longPower = intPower; // int → long: 暗黙的に変換されます。
float floatPower = intPower; // int → float: 暗黙的に変換されます。
double doublePower = intPower; // int → double: 暗黙的に変換されます。
Console.WriteLine("=== 暗黙的な型変換 ===");
Console.WriteLine("int → long: " + longPower);
Console.WriteLine("int → float: " + floatPower);
Console.WriteLine("int → double: " + doublePower);
// 暗黙変換が可能な主な方向: int → long → float → double
// int → float は精度がおよそ7桁に制限されるため、大きな値では誤差が出ます。
int bigInt = 123456789;
float bigFloat = bigInt; // 精度が落ちる可能性があります。
Console.WriteLine("\nbigInt = " + bigInt);
Console.WriteLine("→ float = " + bigFloat); // 123456790 のように丸められます。
// ===== 明示的なキャスト =====
// 大きい型から小さい型、または精度が落ちる変換はキャスト演算子 (型名) を使います。
Console.WriteLine("\n=== 明示的なキャスト ===");
double vegeta = 8500.9;
int castedPower = (int)vegeta; // double → int: 小数部が切り捨てられます。
Console.WriteLine("double: " + vegeta + " → int: " + castedPower);
long frieza = 530_000_000L;
int castedFrieza = (int)frieza;
Console.WriteLine("long: " + frieza + " → int: " + castedFrieza);
// int.MaxValue を超えるとオーバーフローが発生します(デフォルトでは例外なし)。
long overflowVal = 3_000_000_000L; // int の最大値(約21億)を超えています。
int overflowed = (int)overflowVal;
Console.WriteLine("オーバーフロー例: long " + overflowVal + " → int " + overflowed);
// char と int は相互にキャストできます。
char initial = '悟';
int code = (int)initial;
char restored = (char)code;
Console.WriteLine("\n'悟' → int: " + code + " → char: '" + restored + "'");
// ===== Convert クラスによる変換 =====
// キャストではなく Convert クラスを使うと、オーバーフロー時に例外をスローします。
// また、string ↔ 数値の変換にも使えます。
Console.WriteLine("\n=== Convert クラス ===");
string powerStr = "9000";
int parsed = Convert.ToInt32(powerStr); // string → int に変換します。
string backStr = Convert.ToString(parsed); // int → string に変換します。
Console.WriteLine("string → int: " + parsed);
Console.WriteLine("int → string: " + backStr);
double piVal = 3.14159;
int piInt = Convert.ToInt32(piVal); // double → int(四捨五入されます)。
Console.WriteLine("double " + piVal + " → int(四捨五入): " + piInt);
}
}
コンパイルして実行すると次のようになります。
dotnet script TypeConversion.cs === 暗黙的な型変換 === int → long: 9000 int → float: 9000 int → double: 9000 bigInt = 123456789 → float = 123456790 === 明示的なキャスト === double: 8500.9 → int: 8500 long: 530000000 → int: 530000000 オーバーフロー例: long 3000000000 → int -1294967296 '悟' → int: 24735 → char: '悟' === Convert クラス === string → int: 9000 int → string: 9000 double 3.14159 → int(四捨五入): 3
よくあるミス
float / double リテラルに decimal を代入しようとする
decimal 型の変数に数値リテラルを代入するとき、m サフィックスを付け忘れるとコンパイルエラーになります。数値リテラルのデフォルトは double なので、decimal への暗黙変換はできません。
decimal price = 1980.50; // エラー: double から decimal への暗黙変換はできません。 decimal price = 1980.50m;
同様に float にも f サフィックスが必要です。
float speed = 9.8; // エラー: double から float への暗黙変換はできません。 float speed = 9.8f;
float / double の演算で誤差が出る
float と double は2進数で値を保持するため、10進数で正確に表現できない値があります。金額計算で double を使うと意図しない結果になる場合があります。
double a = 0.1 + 0.2; Console.WriteLine(a == 0.3); // False(0.30000000000000004 になるため) decimal b = 0.1m + 0.2m; Console.WriteLine(b == 0.3m); // True
概要
『C#』の基本データ型のうち int / long / double / float / decimal / char / bool は値型(スタックに値そのものが格納)で、string は参照型(ヒープに実体が格納)です。string は参照型ですが不変(immutable)なため、値を「変更」すると内部では新しい文字列オブジェクトが生成されます。元の変数に代入した文字列は変わらないため、値型のように安心して扱えます。
浮動小数点数は double(デフォルト)と float(Unity で多用)を使い分けてください。金融計算など誤差が許されない場面では必ず decimal を使いましょう。float や double は2進数で値を保持するため、0.1 + 0.2 が 0.30000000000000004 になるような誤差が生じる場合があります。
型変換では、小さい型から大きい型への変換(例: int → long)は暗黙的に行われますが、大きい型から小さい型(例: double → int)には明示的なキャスト演算子 (型名) が必要です。キャストで int の範囲を超えた値を変換するとオーバーフローして意図しない値になります。安全に変換したい場合は Convert クラス(オーバーフロー時に例外をスロー)や checked ブロックを使ってください。string と数値の相互変換には Convert.ToInt32() / int.Parse() / int.TryParse() なども参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。