次の方法で共有


C で型を作成する#

このチュートリアルでは、C# で型を作成する方法について説明します。 少量のコードを記述した後、そのコードをコンパイルして実行します。 このチュートリアルには、C# のさまざまな種類の型を調べる一連のレッスンが含まれています。 これらのレッスンでは、C# 言語の基礎について説明します。

ヒント

コード スニペット ブロックに [実行] ボタンが含まれている場合、そのボタンによって対話型ウィンドウが開くか、対話型ウィンドウ内の既存のコードが置き換えられます。 スニペットに [実行] ボタンが含まれていない場合は、コードをコピーして現在の対話型ウィンドウに追加できます。

前のチュートリアルでは、テキストと数字を操作しました。 文字列と数値は 単純型です。それぞれ 1 つの値を格納します。 プログラムの規模が大きくなるにつれて、より高度なデータ構造を使用する必要があります。 C# には、より多くのフィールド、プロパティ、または動作を含むデータ構造が必要な場合に定義できるさまざまな種類の型が用意されています。 これらの型を調べてみましょう。

タプル

タプル は、固定長の値の順序付きシーケンスです。 タプルの各要素には、型と省略可能な名前があります。 次のコードでは、2D ポイントを表すタプルを宣言します。 [実行] ボタンを選択して、次のコードを対話型ウィンドウに貼り付けて実行します。

var pt = (X: 1, Y: 2);

var slope = (double)pt.Y / (double)pt.X;
Console.WriteLine($"A line from the origin to the point {pt} has a slope of {slope}.");

ヒント

C# (または任意のプログラミング言語) を調べるときに、コードを記述するときに間違いを犯します。 コンパイラはこれらのエラーを検出し、報告します。 出力にエラー メッセージが含まれている場合は、対話型ウィンドウのコード例とコードをよく見て、修正する内容を確認します。 この演習は、C# コードの構造を学習するのに役立ちます。

タプルの任意のメンバーを再割り当てできます。 対話型ウィンドウで、既存のコードの後に次のコードを追加します。 [実行] をもう一度押して結果を表示します。

pt.X = pt.X + 5;
Console.WriteLine($"The point is now at {pt}.");

with式を使用して、元の変更されたコピーである新しいタプルを作成することもできます。 対話型ウィンドウで既にコードの後に次のコードを追加し、[実行] を押して結果を表示します。

var pt2 = pt with { Y = 10 };
Console.WriteLine($"The point 'pt2' is at {pt2}.");

タプル pt2には、pt (6) のX値が含まれており、pt2.Yは 10 です。

タプルは構造型です。 つまり、タプル型には、 stringintなどの名前はありません。 タプル型は、 アリティと呼ばれるメンバーの数と、それらのメンバーの型によって定義されます。 メンバー名は便宜上です。 メンバーの名前が異なる場合でも、同じアリティと型を持つタプルにタプルを割り当てることができます。 対話型ウィンドウで既に記述したコードの後に、次のコードを追加して試すことができます。

var subscript = (A: 0, B: 0);
subscript = pt;
Console.WriteLine(subscript);

変数 subscript には 2 つのメンバーがあり、どちらも整数です。 subscriptptはどちらも同じタプル型のインスタンスを表します。2 つのintメンバーを含むタプルです。

タプルは、括弧で囲んだ複数のメンバーを宣言することで、簡単に作成できます。 以下はすべて、異なる引数とメンバー型を持つ異なるタプルを宣言しています。 次のコードを追加して、新しいタプル型を作成します。

var namedData = (Name: "Morning observation", Temp: 17, Wind: 4);
var person = (FirstName: "", LastName: "");
var order = (Product: "guitar picks", style: "triangle", quantity: 500, UnitPrice: 0.10m);

タプルは簡単に作成できますが、その機能は制限されています。 タプル型には名前がないため、値のセットに意味を伝えることはできません。 タプル型は動作を追加できません。 C# には、型が動作を定義するときに作成できる他の種類の型があります。

レコードの種類を作成する

タプルは、同じ構造に複数の値が必要な場合に適しています。 軽量で、使用時に宣言できます。 プログラムが進むにつれて、コード全体で同じタプル型を使用している場合があります。 アプリが 2D グラフ空間で動作する場合は、ポイントを表すタプルが一般的である可能性があります。 見つけたら、それらの値を格納し、より多くの機能を提供する record 型を宣言できます。 次のコード サンプルでは、 Main メソッドを使用してプログラムのエントリ ポイントを表します。 こうすることで、コード内のエントリ ポイントの前に record 型を宣言できます。 次のコードの [実行] ボタンを押して、既存のサンプルを次のコードに置き換えます。

警告

コピーして貼り付けないでください。 次のサンプルを実行するには、対話型ウィンドウをリセットする必要があります。 間違えた場合、ウィンドウがハングし、続行するにはページを更新する必要があります。

次のコードでは、record型を宣言して使用してPointを表し、Main メソッドでそのPoint構造体を使用します。

public record Point(int X, int Y);

public static void Main()
{
    Point pt = new Point(1, 1);
    var pt2 = pt with { Y = 10 };
    Console.WriteLine($"The two points are {pt} and {pt2}");
}

record宣言は、X値とY値を読み取り専用プロパティに格納するPoint型の 1 行のコードです。 この型を使用する際は必ず Point という名前を使用します。 Pointなどの適切な名前の型は、型の使用方法に関する情報を提供します。 Main メソッドは、with式を使用して、既存のポイントの変更されたコピーである新しいポイントを作成する方法を示しています。 行pt2 = pt with { Y = 10 }には、"pt2には、Yが 10 に割り当てられている点を除いて、ptと同じ値があります" と表示されます。1 つのwith式で変更するプロパティをいくつでも追加できます。

上記の record 宣言は、すべての C# ステートメントと同様に、 ;で終わる 1 行のコードです。 メンバーを宣言することで、record型に動作を追加できます。 レコード メンバーには、関数または複数のデータ要素を指定できます。 型のメンバーは、 { 文字と } 文字の間の型宣言にあります。 作成したレコード宣言を次のコードに置き換えます。

public record Point(int X, int Y)
{
    public double Slope() => (double)Y / (double)X;
}

次に、with式を含む行の後に、Main メソッドに次のコードを追加します。

double slope = pt.Slope();
Console.WriteLine($"The slope of {pt} is {slope}");

XY値を表すタプルに形式を追加しました。 名前付き型を定義し、勾配を計算するメンバーを含む record にしました。 record型は、record classの短縮形です。追加の動作を含むclass型です。 Point型を変更して、record structにすることもできます。

public record struct Point(int X, int Y)
{
    public double Slope() => (double) Y / (double) X;
}

record structは、すべてのrecord型に追加される追加の動作を含むstruct型です。

構造体、クラス、およびインターフェイスの型

C# のすべての名前付き型は、 class 型または struct 型です。 class参照型ですstruct値型です。 値型の変数は、インスタンスの内容をメモリ内にインラインで格納します。 つまり、 record struct Point には、 XYの 2 つの整数が格納されます。 参照型の変数は、インスタンスのストレージへの参照またはポインターを格納します。 つまり、 record class Point は、 XYの値を保持するメモリ ブロックへの参照を格納します。

実際には、値型は割り当てられたときにコピーされますが、クラス インスタンスのコピーは参照のコピーであることを意味 します。 コピーされた参照は、 XYの同じストレージを持つポイントの同じインスタンスを参照します。

record修飾子は、いくつかのメンバーを記述するようにコンパイラに指示します。 詳細については、「基礎」セクションの レコードの種類 に関する記事を参照してください。

record型を宣言するときは、型の等価比較、代入、およびコピーインスタンスに既定の動作セットを使用する必要があることを宣言します。 関連するデータを格納することがあなたの型の主な責務である場合、レコードは最適な選択肢です。 さらに動作を追加するときは、record修飾子を使用せずに、struct型またはclass型を使用することを検討してください。

より高度な動作が必要な場合は struct 型を値型に使用しますが、主な役割は値の格納です。 class型を使用して、カプセル化、継承、ポリモーフィズムなどのオブジェクト指向のイディオムを使用します。

interface型を定義して、さまざまな型で実装する必要がある動作コントラクトを宣言することもできます。 struct型とclass型の両方でインターフェイスを実装できます。

通常、これらの型はすべて、大規模なプログラムとライブラリで使用します。 .NET SDK をインストールしたら、基礎セクションの クラス に関するチュートリアルを使用して、これらの型を調べることができます。

「C# で型を作成する」対話型チュートリアルを完了しました。 [Branchs and Loops]\(ブランチとループ\) リンクを選択して次の対話型チュートリアルを開始するか、.NET サイトにアクセスして .NET SDK をダウンロードし、コンピューターにプロジェクトを作成し、コーディングを続けることができます。 「次のステップ」セクションでは、これらのチュートリアルに戻ります。

C# の型の詳細については、次の記事を参照してください。