C Sharp

本書は、マイクロソフト社が開発したプログラミング言語「C#」について解説しています。 C#は、先行するC、C++、Javaと同じファミリーに属するプログラミング言語で、マイクロソフト社の社員が.NET Foundationを通じて開発し、MITライセンスの下でリリースされている共通言語基盤 (Common Language Infrastructure; CLI)で動作することが特徴です。
C#は、多くの開発者によって広く使用されており、プログラミングの初学者から熟練者まで幅広い層に向けて設計されています。また、C#は.NET Frameworkや.NET Coreといったフレームワークを使用して開発することができ、WindowsアプリケーションやWebアプリケーションなどの開発に適しています。
C# はGUIも作成できますが、本ページでは説明の初期のうちは、コンソールアプリ(コマンド プロンプトのような画面にテキスト表示するプログラムのこと)のプログラムを解説したいと思います。
C++になくてC#にある機能は多々ありますが、特にC++との違いが大きい話題を挙げたいと思います。
C#コードで実行中の.NETバージョンを調べるには、次のような方法があります。
C#コンパイラのバージョンを調べるには、次のような方法があります。
このC#のコードは、変数 a の値を文字列に埋め込んで出力するものです。これはC# 6.0から導入された補間文字列(interpolated string)と呼ばれる機能を使用しています。
上記の行は、$ 記号を文字列の前に付けることで補間文字列を作成しています。 C#の補間文字列では、波カッコ {} 内にプレースホルダーを配置します。 これにより、その場所に変数や式の値が埋め込まれます。
ここでは、波カッコ {} 内に変数 a を直接埋め込んでいます。 この記法を使うことで、文字列中に変数の値を直接埋め込むことができます。
補間文字列では単純な変数だけでなく、式も埋め込むことができます。例えば、数値の計算結果や関数の戻り値を埋め込むことができます。
この例では、{} 内に x + y という式があります。 これは変数 x と y の和を計算し、その結果が文字列に埋め込まれます。
補間文字列では、文字列の中に挿入する変数や式に対してフォーマット指定を行うことも可能です。例えば、小数点以下2桁まで表示する場合や日付のフォーマットを指定する場合などに有用です。
この例では、{pi:F2} の部分で pi の値が小数点以下2桁まで表示されます。
補間文字列は可読性が高く、動的な文字列の構築を直感的に行うことができます。 変数や式を {} 内に挿入することで、コードをわかりやすく保ちながら柔軟性を持たせることができます。
特殊文字 @ を前置した文字列リテラルは、逐語的文字列リテラルです。 逐語的文字列リテラルでは、単純なエスケープシーケンス(バックスラッシュを表す「 \ 」など)、16 進エスケープシーケンス(大文字の A を表す「 \x0041 」など)、および Unicode エスケープシーケンス (大文字の A を表す「 \u0041 」など) はそのまま解釈されます。引用符のエスケープシーケンス("")のみ文字通りに解釈されず、二重引用符が1つ生成されます。
C#における配列は、同じ型の複数の要素を保持するデータ構造です。配列は固定長であり、要素数が宣言時に決まります。以下に基本的な配列の使い方を示します。
配列の先頭の要素への添字は 0 です。
配列は要素の型と長さが固定されているため、初期化後に要素数を変更することはできません。要素へのアクセスは、配列名[添え字] のように添え字を用いて行います。配列の要素数は Length プロパティを使って取得できます。また、foreach ループを使って配列の要素を順番に処理することができます。
C#には、プログラミングを効率化するために、あらかじめ、よく使いそうなデータ構造を取り扱う仕組むが言語の機能として提供されています。
標準C言語やC++にない、よく使われる機能が、言語仕様として提供されています。
それを使わずとも、C言語などにある機能だけでもプログラミングは可能ですが、しかしC#の提供する専用機能を使うことで、コードが短くなったり、集団開発ではプログラマーたちによるバラツキが無くなるので品質が一様化して効率化が期待できます。また、コードの各部の意図も、C#の専用機能をつかうことで明確化するので効率化することが期待できます。
このコードでは、Main メソッド内でタプルを作成し、その要素にアクセスしています。
タプルは、異なるデータ型をまとめて1つの変数に格納するための便利な仕組みです。この例では、("John", "Doe") というタプルを作成しています。このタプルには2つの要素が含まれており、1つ目の要素は "John" であり、2つ目の要素は "Doe" です。
Item1 と Item2 は、タプルの要素を参照するためのデフォルトのプロパティ名です。この例では、Item1 は名前、Item2 は姓を表しています。これらの要素にアクセスしてコンソールに出力しています。
タプルは、関連するデータを1つにまとめて扱う際に役立ちます。しかし、要素の名前がないために、コードの読みやすさに影響を及ぼすこともあります。
このように、タプルと foreach ループを組み合わせることで、配列内の各要素を分解し、分かりやすく取り扱うことができます。また、タプルの分解により、コードがより簡潔になり可読性が向上します。
record 型は、C# 9.0で導入された新しいデータ型で、不変(immutable)なデータ構造を定義するのに役立ちます。record はデータのイミュータビリティをサポートし、簡潔なコードでデータの保持と操作を行うための手段となります。
以下は、C#でRecord型を使用したサンプルコードです。
このコードでは、Person Record型を定義する際に、C# 9.0(.NET 5)から導入された短縮構文を使用しています。record キーワードを使って、コンストラクターの引数をフィールドと同時に指定し、簡潔な記述を可能にしています。また、new Person("John", "Doe") のようにコンストラクターを呼び出してインスタンスを生成しています。
record を要素とする配列を作成し、その配列を繰り返し処理する方法を示します。
以下は、C#でRecord型の配列を作成し、それを繰り返し処理するサンプルコードです。
このコードでは、Record型を使ってシンプルなデータモデルを作成し、配列の要素を簡単に操作・表示する方法が示されています。
LINQ(Language Integrated Query)を使用して、Record型の配列要素を繰り返し処理する方法を示すコードを書いてみましょう。
このコードでは、LINQクエリを使ってRecord型の配列要素を繰り返し処理しています。from句を使用してpeople配列内のPerson Record型の要素を取り出し、select句で文字列に変換しています。その後、foreachループを使用してクエリ結果をコンソールに出力しています。
LINQを使うことで、より柔軟なデータのクエリや操作が可能になります。
C#におけるNull許容型(Nullable types)は、通常の値型にnullを許容するための機能です。nullが許容されない通常の値型(int、double、boolなど)では、変数にnullを代入することができませんが、Null許容型を使用することで、nullを含む値を代入できるようになります。
Null許容型は、C# 2.0で導入されました。主な目的は、データベースから取得したデータや他の外部ソースからのデータを扱う際に、nullを適切に処理することです。例えば、データベースの列がnull許容型である場合、その列の値がnullであることを表現できます。 C#では、Null許容型は値型の末尾に「?」を付けることで宣言されます。例えば、int型のNull許容型は「int?」となります。
ここで、"HasValue"プロパティはnullableIntがnullでないかどうかをチェックし、「Value」プロパティは実際の値を取得します。 Null許容型は、プログラムでnullを正しく扱うための重要なツールであり、特に外部リソースやデータベースとのやり取りなどで有用です。
C# 8.0から導入されたNullable Reference Types (null 許容参照型)は、null可能性を表現するための機能です。通常の参照型(クラス、インターフェースなど)はnullを許容しますが、Nullable Reference Typesを使用することで、nullが許容されるかどうかを厳密に指定できます。
この機能を有効にすると、コンパイラがnullに関する潜在的な問題を見つけてくれます。主な機能や使い方は次の通りです:
Nullable Reference Typesは、null関連のバグを減らしたり、コードの安全性を向上させたりするのに役立ちます。しかし、全てのnull関連の問題を解決するわけではないため、コードの品質を維持するためにも、nullに関する適切な扱いが重要です。
以下に、C#のNullable Reference Typesのコード例とその解説を示します。
まず、Nullable Reference Typesを有効にするには、プロジェクトファイルに <Nullable>enable</Nullable> を追加します。
Nullable Reference Typesを使うことで、nullに関する潜在的な問題をコンパイル時に発見し、それらを回避するための対策を行うことができます。
拡張メソッドは、既存の型に新しいメソッドを追加するための仕組みです。これは静的クラスに定義され、対象の型(通常はクラスまたはインタフェース)に対してメソッドを追加します。ただし、拡張メソッドはインスタンスメソッドではなく、静的メソッドであり、そのインスタンスが実際に作成されていないため、ボックス化には直接的な影響を与えません。
このC#のコードは、文字列を逆順にする拡張メソッドを使用する単純な例です。コードの各部分を解説してみましょう。
このプログラムは、originalString の値を ReverseString() で逆順にし、reversedString に格納しています。そして Console.WriteLine() を使ってその逆順の文字列をコンソールに出力しています。
別の例、IntExtensions などのように、int 型に対して拡張メソッドを提供するためのクラスを定義することもできます。C#では、任意の型に対して拡張メソッドを定義することが可能です。
以下は、IntExtensions クラスを使用して int 型に対する拡張メソッドを定義した例です。
この例では、IntExtensions クラスが IsEven() という名前の拡張メソッドを提供しています。これは int 型の変数に対して偶数かどうかを判定する機能を追加します。そして Main() メソッドでこの拡張メソッドを使用して、与えられた整数が偶数か奇数かを判定し、コンソールに出力しています。