ヒント
ソフトウェアの開発は初めてですか? 最初に、 作業の開始 に関するチュートリアルから始めます。 彼らはプログラムの書き方を説明しながら、段階を追って型を紹介していきます。
別の言語で経験がありますか? 型システムを既に理解している場合は、 値と参照 の区別をスキミングし、 型ガイドの種類を選択 してから、特定の型に関する記事に進みます。
C# は厳密に型指定された言語です。 すべての変数、定数、および式には型があります。 コンパイラは、コード内のすべての操作が関連する型に対して有効であることを確認することで、 型の安全性 を強制します。 たとえば、2 つの int 値を追加できますが、 int と boolを追加することはできません。
int a = 5;
int b = a + 2; // OK
bool test = true;
// Error. Operator '+' cannot be applied to operands of type 'int' and 'bool'.
// int c = a + test;
注
C および C++ とは異なり、C# では、 bool は intに変換できません。
型セーフは、コードを実行する前に、コンパイル時にエラーをキャッチします。 コンパイラは、共通言語ランタイム (CLR) が実行時に追加の安全性チェックに使用する、実行可能ファイルに型情報もメタデータとして埋め込みます。
型を使用して変数を宣言する
変数を宣言するときは、その型を明示的に指定するか、 var を使用して、コンパイラが代入された値から型を推論できるようにします。
// Explicit type:
int count = 10;
double temperature = 36.6;
// Compiler-inferred type:
var name = "C#";
var items = new List<string> { "one", "two", "three" };
メソッド パラメーターと戻り値にも型があります。 次のメソッドは、 string と intを受け取り、 stringを返します。
static string GetGreeting(string name, int visitCount)
{
return visitCount switch
{
1 => $"Welcome, {name}!",
_ => $"Welcome back, {name}! Visit #{visitCount}."
};
}
変数を宣言した後は、その型を変更したり、宣言された型と互換性のない値を割り当てたりすることはできません。 値を他の型に変換できます。 コンパイラは、データを自動的に失わない 暗黙的な変換 を実行します。 明示的な変換 (キャスト) では、コード内の変換を示す必要があります。 詳細については、「 キャストと型変換」を参照してください。
組み込み型とカスタム型
C# には、整数、浮動小数点数、、bool、charなどの一般的なデータ用のstringが用意されています。 すべての C# プログラムでは、追加の参照なしでこれらの組み込み型を使用できます。
組み込み型以外にも、いくつかのコンストラクトを使用して独自の型を作成できます。
- クラス - モデリング動作と複雑なオブジェクトの参照型。 継承とポリモーフィズムをサポートします。
- 構造体 - 小規模で軽量なデータの値型。 各変数は、独自のコピーを保持します。
-
レコード —
ToString式を介してコンパイラによって生成された等値、with、および非破壊的変更を持つクラスまたは構造体。 - インターフェイス — 任意のクラスまたは構造体が実装できるメンバーを定義するコントラクト。
- 列挙 — 曜日やファイル アクセス モードなど、整数定数の名前付きセット。
- タプル - 名前付き型を定義せずに関連する値をグループ化する軽量構造型。
-
ジェネリック — 型の安全性を提供しながら、異なる型に対して同じロジックを再利用する、
List<T>やDictionary<TKey, TValue>などの型パラメーター化されたコンストラクト。
値型と参照型
C# のすべての型は、 値型 または 参照型です。 この区別によって、変数がデータを格納する方法と割り当てのしくみが決まります。
値型 は、データを直接保持します。 新しい変数に値型を割り当てると、ランタイムによってデータがコピーされます。 1 つの変数に対する変更は、もう一方の変数には影響しません。 構造体、列挙型、および組み込みの数値型はすべて値型です。
参照型 は、マネージド ヒープ上のオブジェクトへの参照を保持します。 新しい変数に参照型を割り当てると、両方の変数が同じオブジェクトを指します。 一方の変数を介した変更は、もう一方の変数を通じて表示されます。 クラス、配列、デリゲート、および文字列は参照型です。
次の例は、その違いを示しています。 最初のブロックは、 Coords レコード構造体 (値型) の定義を示しています。 2 番目のブロックは、値型と参照型に対して異なる動作を示しています。
public readonly record struct Coords(int X, int Y);
// Value type: each variable holds its own copy
var point1 = new Coords(3, 4);
var point2 = point1;
Console.WriteLine($"point1: ({point1.X}, {point1.Y})");
Console.WriteLine($"point2: ({point2.X}, {point2.Y})");
// point1 and point2 are independent copies
// Reference type: both variables refer to the same object
var list1 = new List<int> { 1, 2, 3 };
var list2 = list1;
list2.Add(4);
Console.WriteLine($"list1 count: {list1.Count}"); // 4 — same object
すべての型は最終的に System.Objectから派生します。 値型は System.ValueTypeから、そして System.ValueTypeは から派生します。 この統合階層は、 共通型システム (CTS) と呼ばれます。 継承の詳細については、「 継承」を参照してください。
どの種類を選ぶか選択してください
新しい型を定義する際に選択する種類は、コードの動作を形作ります。 最初の決定を行うには、次のガイドラインを使用します。
- タプル - 名前付きの型や動作を必要としない値の一時的なグループ化。
-
structまたはrecord struct— 小さなデータ (約 64 バイト以下)、値のセマンティクス、または不変性。 レコード構造体は、値ベースの等価性とwith式を追加します。 -
record class— 主に、値に基づく等価性、ToString、非破壊的変異を持つデータ。 継承をサポートします。 -
class— 複雑な動作、ポリモーフィズム、または変更可能な状態。 ほとんどのカスタム型はクラスです。 -
interface— 関連のない型が実装できるコントラクト。 ID ではなく機能を定義します。 -
enum— ステータス コードやオプションなど、名前付き定数の固定セット。
多くの場合、複数のオプションが妥当です。
コンパイル時の型と実行時の型
変数は、コンパイル時と実行時に異なる型を持つことができます。 コンパイル時の型は、ソース コードで宣言または推論された型です。 ランタイム型は、変数が参照するインスタンスの実際の型です。 実行時の型は、コンパイル時の型と同じか、そこから派生または実装する型である必要があります。 割り当ては、実行時の型からコンパイル時の型への暗黙的な変換 (ID、参照、ボックス化、数値変換など) が存在する場合にのみ有効です。
// Compile-time and run-time types match:
string message = "Hello, world!";
// Compile-time type differs from run-time type:
object boxed = "This is a string at run time";
IEnumerable<char> characters = "abcdefghijklmnopqrstuvwxyz";
前の例では、 boxed のコンパイル時の型は object ですが、実行時の型は stringです。 割り当ては、 string が objectから派生しているために機能します。 同様に、 characters にはコンパイル時の型の IEnumerable<char>があり、 string はそのインターフェイスを実装しているため、割り当てが機能します。 コンパイル時の型は、オーバーロードの解決と使用可能な変換を制御します。 ランタイム型は、仮想メソッドディスパッチ、 is 式、および switch 式を制御します。
こちらも参照ください
C# 言語仕様
詳細については、C# 言語仕様のを参照してください。 言語仕様は、C# の構文と使用法の決定的なソースです。
.NET