C Sharp

**C#**（シーシャープ）は、マイクロソフトが開発した汎用かつマルチパラダイムなプログラミング言語。

## 概要

開発にはボーランドのTurbo PascalやDelphiを開発したアンダース・ヘルスバーグを筆頭として多数のDelphi開発陣が参加している。構文はC系言語（C言語、C++、Javaなど）の影響を受けており、その他の要素には、以前、ヘルスバーグが所属していたボーランド設計のDelphiの影響が見受けられる。また、主要言語へのasync/await構文や、ヘルスバーグが言語設計に関わるTypeScriptでのジェネリクス採用など、他言語への影響も見られる。

C#は共通言語ランタイム（CLR）などの共通言語基盤（CLI）が解釈する共通中間言語（CIL）にコンパイルされて実行される。

また、C#はマルチパラダイムをサポートする汎用高レベルプログラミング言語で、静的型付け、タイプセーフ、スコープ、命令型、宣言型、関数型、汎用型、オブジェクト指向（クラスベース）、コンポーネント指向のプログラミング分野を含んでいる。他にも自動ボックス化、デリゲート、プロパティ、インデクサ、カスタム属性、ポインタ演算操作、構造体（値型オブジェクト）、多次元配列、可変長引数、async/await構文、null安全などの機能を持つ。また、Javaと同様に大規模ライブラリ、プロセッサ・アーキテクチャに依存しない実行形態、ガベージコレクション、JITコンパイルによる実行の高速化、AOTコンパイラによる高速実行、などが実現されている（もっともこれらはC#の機能というより.NET によるものである）。

共通言語基盤といった周辺技術も含め、マイクロソフトのフレームワークである**「.NET」**の一部である。また、以前のVisual J++で「非互換なJava」をJavaに持ち込もうとしたマイクロソフトとは異なり、その多くの仕様を積極的に公開し、ECMAやISOなど標準化機構に託して自由な利用を許すなど、同社の姿勢の変化があらわれている。

.NET構想における中心的な開発言語であり、XML WebサービスやASP.NETの記述にも使用される。他の.NET系の言語でも記述可能だが、.NET APIはC#からの利用を第一に想定されており、他の.NET系言語（特に2023年以降新構文の追加なしと宣言されたVB.NET）では利用できない、あるいは将来的に利用できなくなる機能が存在する。

C#は、Windowsの.NET Framework上で動作することを前提として開発された言語であった。2016年6月からはクロスプラットフォームな.NETランタイム上で動作する。Microsoft Windowsを含む複数のデスクトップ環境、ウェブアプリ・ウェブサービス（ASP.NET、ASP.NET Coreなど）、クラウドコンピューティング、モバイル、ゲーム開発（ゲームエンジンのUnityなど）などで採用されている。

マイクロソフトの統合開発環境（Microsoft Visual Studio）では、Microsoft Visual C#がC#に対応している。また、Visual Studio Codeに専用のC#向け拡張（C# DevKit）を導入することでクロスプラットフォームで開発することが可能。

共通言語仕様のCLSによって、他のCLS準拠の言語（F#やVisual Basic .NET、C++/CLIなど）と相互に連携することができる。

## バージョンおよびリリース時期

## 言語仕様
、基盤である共通言語基盤（CLI）の多くの機能を反映している言語であるといえる。C#にある組み込み型のほとんどは、共通言語基盤のフレームワークに実装されている値型と対応している。

しかし、C#の言語仕様はコンパイラのコード生成については何も言及していないため、CLRに対応しなければならないとか、 CILなどの特定のフォーマットのコードを生成しなければならないとかいうことは述べられていない。

そのため、理論的にはC++やFORTRANのように環境依存のマシン語を生成することも可能である。しかし、現在存在するすべてのC#コンパイラはCLIをターゲットにしている。

.NET 7.0以降で可能になった事前コンパイルの一種である**「Native AOT」**でデプロイすることで実行可能な環境依存のバイナリを出力することが可能である。しかしながらこの手法もCLIとランタイムを事前に各アーキテクチャ向けのバイナリに変換しているだけであり、CLIを経由することに変わりはない。

特殊な例としては、UnityのScripting Backendである「IL2CPP」や「Burst」がある。IL2CPPはC#をコンパイルしたCILをさらにC++コードへと変換後、ネイティブバイナリへC++コンパイラによってコンパイルされる。BurstはC#をコンパイルしたCILをLLVMコンパイラによってネイティブバイナリへコンパイルするものである。

### Hello World
最新のC#ではHello Worldを下記の通りに1行で記述できる。


```csharp
Console.WriteLine("Hello World!");
```


上記のコードは、コンパイラによって下記の様なコードに展開される。


```csharp
using System;

namespace Wikipedia
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}
```


次の言語機能によって実現されている。ただし、未対応の古いコンパイラを用いる場合は、省略できない。
* C# 9.0  にて導入された最上位レベルのステートメント
* C# 10.0 にて導入された暗黙的な`using`

### CやC++からの改良点
C#では、CやC++と比較してさまざまな制限や改良が加えられている。また、仕様の多くはC#言語というよりは、基盤である.NETそのものに依拠している。Javaで導入された制限および改良をC#でも同様に採用しているものが多いが、C#で新たに導入された改良がのちにJavaにも同様に採用されたものもある。その例を次に挙げる。

#### 構文や構文以外の改良点
* 外のブロックで宣言した変数と同じ名前の変数を、内のブロックで再宣言（シャドウ）してはいけない。再宣言は便利なこともあれば、混乱や曖昧のもとと主張されることもあるが、C#では禁止されている。
* C#にはブール型`bool`が存在し、`[[while文|while]]`文や`[[if文|if]]`文のように条件をとるステートメントには、`bool`型の式を与えなければならない。C言語では、ブール型が無く`int`型（0を偽とし、非0を真とする）に兼用させた上、（ヌルポインタを偽とみなすこととするといろいろと便利だった、ということもあり）ポインタでも`while`文や`if`文に与える式にできる、という仕様としていた。これは便利なこともあったが、本来比較式を記述すべきところで誤って代入式を記述してもコンパイル適合となってしまうなど、ミスが見逃されることもあった。C#ではに、そのような仕様ではなくブール型を独立させ、またブール型を厳密に要求する場所を多くしている。
* `[[switch文|switch]]`文に整数型あるいは整数型に準ずる型のみならず、文字列型`string`を使用できる。`case`ラベルには、整数型あるいは整数型に準ずる型の定数のみならず、文字列リテラル（文字列定数）を使用できる。
** C# 7.0 以降では `case`ラベルに複雑なパターンマッチングを行うことが可能で複雑な判定を簡易な記述で記載が可能。
* 組み込み型のサイズおよび内部表現が仕様で定められており、プラットフォームや処理系に依存しない。浮動小数点数はIEEE 754に準拠する。文字および文字列はUTF-16エンコーディングを採用する。
** C# 9.0以降では CPUによってサイズの異なる整数型`nint/nuint`が追加された。
** C# 11.0 以降では文字列をUTF-8として扱う「UTF-8文字列リテラル」が追加された。

#### ポインタとメモリ管理
* ポインタをサポートする。ポインタは`unsafe`スコープ内のみで使用することができ、適切な権限をもつプログラムのみが`unsafe`とマークされたコードを実行することができる。オブジェクトへのアクセスの大部分は管理された安全な参照によってなされ、大部分の算術演算はオーバフローのチェックがなされる。`unsafe`ポインタは値型や文字列を指すことができる。セーフコードでは、必ずしもそうする必要はないものの、`IntPtr`型を通してポインタをやりとりすることができる。
* マネージドなメモリを明示的に解放する方法は存在せず、参照されなくなったメモリはガベージコレクタによって自動的に解放される。ガベージコレクタは、メモリの解放忘れによって起こるメモリリークを解消する。C#は、データベース接続のようなアンマネージドなリソースに対しても明示的に制御する方法を提供している。これは`IDisposable`インタフェースと`using`ステートメントまたは`using`宣言によってなされる。

#### 名前空間とオブジェクト指向な型システム
* グローバル変数やグローバルメソッドは存在しない。すべてのフィールドとメソッドはクラスあるいは構造体の一部として宣言されなければならない。
: 例えばC/C++の`[[printf]]()`関数のように名前空間レベルに存在するフリー関数を定義することはできない。ほとんどの場合クラスおよび構造体は名前の衝突を避けるために名前空間に所属する。
* 名前空間は階層構造をもつ。つまり、名前空間は他の名前空間の中に宣言することができる。
* 組み込みの値型を含めたすべての型は、`object`クラス (`System.Object`) の派生型である。つまり`object`クラスのもつすべてのプロパティやメソッドを継承する。例えば、すべての型は`ToString()`メソッドをもつ。
* クラス (`class`) は参照型であり、構造体 (`struct`) および列挙型 (`enum`) は値型である。構造体はクラスよりも軽量で、C/C++との相互運用性に優れるが、派生型を定義することができない。
* クラスおよび構造体は複数のインタフェースを実装することができるが、多重継承はサポートされない。
* C#はC++に比べて型安全である。既定の暗黙変換は、整数の範囲を広げる変換や、派生クラスから基底クラスへの変換といった、安全な変換のみに限定される。これは、コンパイル時、JITコンパイル時、そして一部の動的なケースでは実行時に強制される。ブール型と整数型、列挙型と整数型、の間は暗黙変換はできない。暗黙変換をユーザー定義する際は、明示的にそのように指定しなければならない。これはC++のコンストラクタとは違った仕様である。
* C#は「Null安全」である。Null許容型、Null許容参照型を持ち、Null合体演算子などの構文・演算子を持つ。
* 列挙型のメンバーは、列挙型のスコープの中に置かれる。また、列挙型の定数名を取得することができる。さらに、列挙型の定数名から動的に定数値を得ることができる。
* アクセサの定義と利用を簡略化するためにプロパティ構文を利用できる。C++およびJavaにおけるカプセル化では、通例getter/setterアクセサとなるメンバー関数あるいはメソッドを定義して利用するが、C#ではプロパティ機能により、カプセル化を維持しつつ、あたかもフィールドを直接読み書きするような直感的な構文でオブジェクトの状態にアクセスすることができる。プロパティによってメンバーのアクセス制御やデータの正当性チェックを実行することができる。なお、イベントハンドラーに利用するデリゲートのカプセル化にはイベント構文 (`event`) が用意されている。
* ジェネリクス（総称型）の採用（C# 2.0以降）。C++のテンプレート、Javaのジェネリックスと異なりコンパイル後も型情報が保持される。また、Javaのジェネリクスと異なりプリミティブ型も型変数として使うことができる。

### C# 2.0からの仕様
#### 部分型
部分型（英: ）が導入された。以下のようにクラスや構造体の宣言に`partial`修飾子をつけることで、その宣言を分割することができる。


```csharp
partial class MyClass { int a; }
partial class MyClass { int b; }
```


これは以下と同義である。

```csharp
class MyClass { int a; int b; }
```


これによって、巨大なクラスを分割したり、自動生成されたコードを分離したりすることができる。`partial`修飾子はすべての宣言につける必要がある。

#### ジェネリクス

ジェネリクスが導入された。これは.NET Framework 2.0の機能である。クラス、構造体、インタフェース、デリゲート、メソッドに対して適用することができる。

.NETのGenericsはC++のテンプレート、あるいはJavaにおけるそれとも異なるもので、コンパイルによってではなく実行時にランタイムによって特殊化される。これによって異なる言語間の運用を可能にし、リフレクションによって型パラメーターに関する情報を取得することができる。また、`where`節によって型パラメーターに制約を与えることができる。一方、C++のように型パラメーターとして式を指定することはできない。なお、ジェネリックメソッドの呼び出し時に引数によって型パラメーターが推論できる場合、型パラメーターの指定は省略できる。

#### 静的クラス
静的クラスが導入された。`static`属性をクラスの宣言につけることで、クラスはインスタンス化できなくなり、静的なメンバーしか持つことができなくなる。

##### yieldキーワード
`yield`キーワードによるコルーチンを使うことで、イテレータの生成を楽に実装できるようになった。

#### 匿名デリゲート
クロージャの機能を提供する匿名デリゲートが導入された。

#### プロパティに対する個別のアクセス制御
プロパティの`get`もしくは`set`アクセサのどちらかにアクセス修飾子を指定することでアクセス制御が別個にできるようになった。次の例では、`get`アクセサは`public`、`set`アクセサは`private`である。


```csharp
public class MyClass
{
  private string status = string.Empty;
  public string Status
  {
    get { return status; }
    private set { status = value; }
  }
}
```


#### Null許容型とnull結合演算子

nullを保持できる値型、`Nullable`が導入された。


```csharp
int? i = 512;
i = null;

int? j = i + 500; //jはnullとなる。nullとの演算の結果はnullになる。
```


`int?`は`Nullable<int>`の糖衣構文である。また、`null`を保持しているNull許容型のインスタンスをボックス化しようとすると、単に空参照（null）に変換される。


```csharp
int? x = null;
object o = x;
System.Console.WriteLine(o == null); //Trueが出力される
```


また、null結合演算子 (`??`)が導入された。これは、`null`でない最初の値を返す。


```csharp
object obj1 = null;
object obj2 = new object();
object obj3 = new object();
return obj1 ?? obj2 ?? obj3; // obj2 を返す
```


この演算子は主に`Nullable`型を非`Nullable`型に代入するときに使われる。


```csharp
int? i = null;
int j = i ?? -1; // nullをint型に代入することはできない
```


#### その他
* イテレータ
* 匿名メソッド
* External Aliases/Namespace Aliases Qualifiers
* プラグマディレクティブ/C言語の様な固定長の配列表記

### C# 3.0からの仕様

#### varキーワード
`var` キーワードが導入され、型推論を利用したローカル変数の宣言ができるようになった。

```csharp
var s = "foo";
// 上の文は右辺が string 型であるため、次のように解釈される:
string s = "foo";
// 以下に挙げる文は誤りである（コンパイルエラーとなる）:
var v; // 初期化式を欠いている (型を推論する対象が存在しない)
var v = null; // 型が推論できない (曖昧である)
```


#### 拡張メソッド
拡張メソッド（英: ）が導入された。既存のクラスを継承して新たなクラスを定義することなく、新たなインスタンスメソッドを疑似的に追加定義することができる。具体的には、入れ子になっていない、非ジェネリックの静的クラス内に、`this` 修飾子をつけた、拡張メソッドを追加する対象の型の引数を最初に持つメソッドをまず定義する。これによって、通常の静的メソッドとしての呼び出しの他に、指定した型のインスタンスメソッドとしての呼び出しを行うことができるメソッドを作ることができる。以下に例を挙げる:

```csharp
public static class StringUtil
{
  public static string Repeat(this string str, int count)
  {
    var array = new string[count];
    for (var i = 0; i < count; ++i) array[i] = str;
    return string.Concat(array);
  }
}
```

この例は、文字列（`string`型のインスタンス）を指定した回数繰り返し連結したものを返すメソッド`Repeat`を、既存の`string`型に追加している。このメソッドは、以下のように呼び出すことができる:

```csharp
// 静的メソッドとしての呼び出し
StringUtil.Repeat("foo", 4);
// 拡張メソッドとしての呼び出し
"foo".Repeat(4);
// (どちらの例も "foofoofoofoo" を返す)
```

また、列挙型やインタフェースなど本来メソッドの実装を持ち得ない型に、見かけ上インスタンスメソッドを追加することも可能である。以下に例を挙げる:

```csharp
public enum Way
{
  None, Left, Right, Up, Down
}

public static class EnumUtil
{
  public static Way Reverse(this Way src)
  {
    switch (src)
    {
      case Way.Left:  return Way.Right;
      case Way.Right: return Way.Left;
      case Way.Up:    return Way.Down;
      case Way.Down:  return Way.Up;
      default: return Way.None;
    }
  }
}
```

このメソッドは以下のように呼び出すことができる:

```csharp
Way l = Way.Left;
Way r = l.Reverse(); // Way.Right
```


拡張メソッドは糖衣構文の一種であり、カプセル化の原則に違反するものではないが、必要な場合に限り注意して実装することがガイドラインとして推奨されている。

#### 部分メソッド
部分メソッドが導入された。部分型（`partial`型）内で定義された`private`で、かつ戻り値が `void`のメソッドに `partial`修飾子をつけることでメソッドの宣言と定義を分離させることができる。定義されていない部分メソッドは何も行わず、何らエラーを発生させることもない。例えば:

```csharp
partial class Class
{
  partial void DebugOutput(string message);
  
  void Method()
  {
    DebugOutput("Some message");
    Console.WriteLine("Did something.");
  }
}
```

上のコードにおいて `Method()` を呼び出すと、Did something. と表示されるだけだが、ここで以下のコード:

```csharp
partial class Class
{
  partial void DebugOutput(string message)
  {
    Console.Write("[DEBUG: {0}] ", message);
  }
}
```

を追加した上で`Method()`を呼び出すと、[DEBUG: Some message] Did something.と表示される。

#### ラムダ式
ラムダ式が導入された。この名前はラムダ計算に由来する。

以下の匿名メソッド

```csharp
// iを変数としてi+1を返すメソッド
delegate (int i) { return i + 1; }
```

は、ラムダ式を使って次のように記述できる:

```csharp
(int i) => i + 1; /* 式形式のラムダ */
//或いは:
(int i) => { return i + 1; }; /* ステートメント形式のラムダ */
```

ラムダ式は匿名メソッドと同様に扱えるが、式形式のラムダが`Expression<TDelegate>`型として扱われた場合のみ匿名メソッドとして扱われず、コンパイラによって式木を構築するコードに変換される。匿名デリゲートが実行前にコンパイルされたCILを保持するのに対し、式木はCILに実行時コンパイル可能であるDOMのような式の木構造そのものを保持する。これはLINQクエリをSQLクエリなどに変換する際に役立つ。

以下は、3つの任意の名前の変数、整数、括弧、及び四則演算子のみで構成された式を逆ポーランド記法に変換する汎用的なコードである:

```csharp
public static string ToRPN(Expression<Func<int, int, int, int>> expression)
{
  return Parse((BinaryExpression) expression.Body).TrimEnd(' ');
}

private static string Parse(BinaryExpression expr)
{
  string str = "";
  
  if (expr.Left is BinaryExpression)
  {
    str += Parse((BinaryExpression) expr.Left);
  }
  else if (expr.Left is ParameterExpression)
  {
    str += ((ParameterExpression) expr.Left).Name + " ";
  }
  else if (expr.Left is ConstantExpression)
  {
    str += ((ConstantExpression) expr.Left).Value + " ";
  }

  if (expr.Right is BinaryExpression)
  {
    str += Parse((BinaryExpression) expr.Right);
  }
  else if (expr.Right is ParameterExpression)
  {
    str += ((ParameterExpression) expr.Right).Name + " ";
  }
  else if (expr.Right is ConstantExpression)
  {
    str += ((ConstantExpression) expr.Right).Value + " ";
  }
  
  return str + expr.NodeType.ToString()
    .Replace("Add", "+")
    .Replace("Subtract", "-")
    .Replace("Multiply", "*")
    .Replace("Divide", "/")
    + " ";
}

// 呼び出し例:
ToRPN((x, y, z) => (x + 1) * ((y - 2) / z)); // "x 1 + y 2 - z / *" を返す
```


#### オブジェクト初期化の簡略化
オブジェクトの初期化が式として簡潔に記述できるようになった。

```csharp
var p = new Point { X = 640, Y = 480 };
// 上の文は次のように解釈される:
Point __p = new Point();
__p.X = 640;
__p.Y = 480;
Point p = __p;
```

また、コレクションの初期化も同様に簡潔に記述できるようになった。

```csharp
var l = new List<int> {1, 2, 3};
var d = new Dictionary<string, int> ;
// 上の文は次のように解釈される:
List<int> __l = new List<int>();
__l.Add(1);
__l.Add(2);
__l.Add(3);
List<int> l = __l;
Dictionary<string, int> __d = new Dictionary<string, int>();
__d.Add("a", 1);
__d.Add("b", 2);
__d.Add("c", 3);
Dictionary<string, int> d = __d;
```

但し、上のコードでは匿名の変数に便宜的に __p、__l、__d と命名している。実際はプログラマはこの変数にアクセスすることはできない。

#### 自動実装プロパティ
プロパティをより簡潔に記述するための自動実装プロパティが導入された。プロパティの定義に`get; set;`と記述することで、プロパティの値を保持するための匿名のフィールド（プログラマは直接参照することはできない）と、そのフィールドにアクセスするためのアクセサが暗黙に定義される。また、C# 5.0までは `get;`と`set;`のどちらか片方だけを記述することは出来なかったが、C# 6.0からは`get;`のみが可能。以下のコード:

```csharp
public int Value { get; set; }
```

は、以下のようなコードに相当する動作をする:

```csharp
private int __value;
public int Value
{
  get { return __value; }
  set { __value = value; }
}
```

但し、上のコードでは匿名のフィールドに便宜的に`__value`と命名している。実際はプログラマはこのフィールドにアクセスすることはできない。

#### 匿名型
一時的に使用される型を簡単に定義するための匿名型が導入された。以下に例を挙げる:

```csharp
new { Name = "John Doe", Age = 20 }
```

上の式は、以下の内容のクラスを暗黙に定義する。定義されたクラスは匿名であるが故にプログラマは参照できない。

```csharp
public string Name { get; }
public int Age { get; }
```

同じ型、同じ名前のプロパティを同じ順序で並べた匿名型は同じであることが保証されている。即ち、以下のコード:

```csharp
var her = new { Name = "Jane Doe", Age = 20 }
var him = new { Name = "John Doe", Age = 20 }
```

において、`her.GetType() == him.GetType()`は`true`である。

#### 配列宣言の型省略
`new`キーワードを用いた配列の宣言の際、型を省略できるようになった。匿名型の配列を宣言する際に威力を発揮する。

```csharp
var a = new[] {"foo", "bar", null};
// 上の文は次のように解釈される:
string[] a = new string[] {"foo", "bar", null};
// 以下の文:
var a = new[] {"foo", "bar", 123};
// は次のように解釈されることなく、誤りとなる:
object[] a = new object[] {"foo", "bar", 123};
```


#### クエリ式
LINQをサポートするために、クエリ式が導入された。これはSQLの構文に類似しており、最終的に通常のメソッド呼び出しに変換されるものである。以下に例を示す:

```csharp
var passedStudents =
  from s in students
  where s.MathScore + s.MusicScore + s.EnglishScore > 200
  select s.Name;
```

上のコードは以下のように変換される:

```csharp
var passedStudents = students
  .Where(s => s.MathScore + s.MusicScore + s.EnglishScore > 200)
  .Select(s => s.Name);
```

C# 3.0で追加された構文の多くは式であるため、より巨大な式（当然クエリ式も含まれる）の一部として組み込むことができる。旧来複数の文に分けたり、作業用の変数を用意して記述していたコードを単独の式としてより簡潔に記述できる可能性がある。

出井秀行著の『実戦で役立つ C#プログラミングのイディオム/定石&パターン』（技術評論社、2017年）という書籍ではクエリ構文よりメソッド構文を推奨しており、クエリ構文ではLINQの全ての機能を使用できるわけではないこと、メソッド呼び出しは処理を連続して読める可読性があること、メソッド呼び出しであればMicrosoft Visual Studioの強力なインテリセンスが利用できることを理由に、著者はクエリ構文をほとんど使用していないと記している。

### C# 4.0からの仕様

#### dynamicキーワード
dynamicキーワードが導入され、動的型付け変数を定義できるようになった。dynamic型として宣言されたオブジェクトに対する操作のバインドは実行時まで遅延される。

```csharp
// xはint型と推論される:
var x = 1; 
// yはdynamic型として扱われる:
dynamic y = 2; 

public dynamic GetValue(dynamic obj)
{
  // objにValueが定義されていなくとも、コンパイルエラーとはならない:
  return obj.Value;
}
```


#### オプション引数・名前付き引数
VBやC++に実装されているオプション引数・名前付き引数が、C#でも利用できるようになった。

```csharp
public void MethodA()
{
  // 第1引数と第2引数を指定、第3引数は未指定:
  Console.WriteLine("Ans: " + MethodB(1, 2));  // Ans: 3 … 1 + 2 + 0となっている

  // 第1引数と第3引数を指定、第2引数は未指定:
  Console.WriteLine("Ans: " + MethodB(A: 1, C: 3));  // Ans: 4 … 1 + 0 + 3となっている
}

// 引数が指定されなかった場合のデフォルト値を等号で結ぶ:
public int MethodB(int A = 0, int B = 0, int C = 0)
{
  return A + B + C;
}
```


#### ジェネリクスの共変性・反変性
ジェネリクスの型引数に対してin、out修飾子を指定することにより、ジェネリクスの共変性・反変性を指定できるようになった。

```csharp
IEnumerable<string> x = new List<string> { "a", "b", "c" };
// IEnumerable<T>インターフェイスは型引数にout修飾子が指定されているため、共変である。
// したがって、C# 4.0では次の行はコンパイルエラーにならない
IEnumerable<object> y = x;
```


### C# 5.0からの仕様
* 非同期処理（Async/await）
* 呼び出し元情報属性
* foreach の仕様変更

### C# 6.0からの仕様
* 自動実装プロパティの初期化子
* getのみの自動実装プロパティおよびコンストラクタ代入

* 静的usingディレクティブ
* インデックス初期化子
* catch/finallyでのawait
* 例外フィルタ
* 式形式のメンバー（expression-bodied members）
* null条件演算子
* 文字列補間（テンプレート文字列）
* nameof演算子
* #pragma
* コレクションの初期化子での拡張メソッド
* オーバーロード解決の改善

#### 静的 using ディレクティブ
静的usingディレクティブを利用することで、型名の指定無しに他クラスの静的メンバーの呼び出しを行えるようになった。利用するには`using static`の後に完全修飾なクラス名を指定する。


```csharp
using static System.Math;
// ↑ソースコードの上部で宣言
class Hogehoge {
    // System.Math.Pow() , System.Math.PI を修飾無しで呼び出す
    double area = Pow(radius, 2) * PI;
}
```


#### 例外フィルタ
`catch`の後に`when`キーワードを使用することで、処理する例外を限定することができるようになった。


```csharp
try {
    // ...
}
catch (AggregateException ex) when (ex.InnerException is ArgumentException) {
    // ...
}
```


### C# 7.0からの仕様
* 出力変数宣言
* パターンマッチング（is式/switch文）
* タプル（タプル記法/分解/値の破棄）
* ローカル関数
* 数値リテラルの改善（桁セパレータ/バイナリリテラル）
* ref戻り値、ref変数
* 非同期戻り値型の汎用化
* Expression-bodied機能の拡充（コンストラクタ/デストラクタ/get/set/add/remove）
* Throw式

#### 出力変数宣言
`out`引数で値を受け取る場合、その場所で変数宣言可能となった。


```csharp
total += int.TryParse("123", out var num) ? num : 0;
```


#### パターンマッチング

##### is 式の拡張
`is`式の構文が拡張され、型の後ろに変数名を宣言できるようになった。拡張された`is`式はマッチした場合に宣言した変数にキャストした値を代入し、さらに**true**と評価される。マッチしなかった場合は**false**と評価され、宣言した変数は未初期化状態となる。


```csharp
void CheckAndSquare(object obj) {
    // objの型チェックと同時にnumに値を代入する。
    if (obj is int num && num >= 0) {
        num = num * num;
    }
    else {
        num = 0;
    }
    // if文の条件セクションは、ifの外側と同じスコープ
    Console.WriteLine(num);
}
```


##### switch 文の拡張
`switch`文のマッチ方法が拡張され、`case`ラベルに従来の「定数パターン」に加え、新たに「型パターン」を指定できるようになった。また、「型パターン」の`case`ラベルでは、`when`句に条件を指定することができる。「型パターン」を含む`switch`文では、必ずしも条件が排他的でなくなったため、最初にマッチした`case`ラベルの処理が実行される。


```csharp
void Decide(object obj) {
    switch (obj) {
        case int num when num < 0:
            Console.WriteLine($"{num}は負の数です。");
            break;
        case int num:
            Console.WriteLine($"{num}を二乗すると{num * num}です。");
            break;
        case "B":
            Console.WriteLine($"これはBです。");
            break;
        case string str when str.StartsWith("H"):
            Console.WriteLine($"{str}はHから始まる文字列です。");
            break;
        case string str:
            Console.WriteLine($"{str}は文字列です。");
            break;
        case null:
            Console.WriteLine($"nullです");
            break;
        default:
            Console.WriteLine("判別できませんでした");
            break;
    }
}
```


#### タプル
タプルのための軽量な構文が導入された。従来の`System.Tuple`クラスとは別に、`System.ValueTuple`構造体が新しく追加された。

##### タプル記法
2個以上の要素を持つタプルのための記法が導入された。引数リストと同様の形式で、タプルを記述できる。


```csharp
// タプル記法
(int, string) tuple = (123, "Apple");
Console.WriteLine($"{tuple.Item1}個の{tuple.Item2}");
```


##### 分解
多値戻り値を簡単に扱えるように、分解がサポートされた。


```csharp
var tuple = (123, "Apple");
// 分解
(int quantity, string name) = tuple;
Console.WriteLine($"{quantity}個の{name}");
```


分解はタプルに限らない。`Deconstruct()`メソッドが定義されたクラスでも、分解を利用できる。

以下に、`DateTime`型に分解を導入する例を示す。


```csharp
static class DateExt {
    public static void Deconstruct(this DateTime dateTime, out int year, out int month, out int day) {
        year = dateTime.Year;
        month = dateTime.Month;
        day = dateTime.Day;
    }
}
```

上記のコードで`DateTime`型に`Deconstruct()`拡張メソッドを定義し、

```csharp
// 分解
(int year, int month, int day) = DateTime.Now;
```

のように左辺で3つの変数に値を受け取ることができる。

#### 値の破棄
分解、out引数、パターンマッチングで、値の破棄を明示するために`_`が利用できるようになった。破棄された値は、後で参照することはできない。


```csharp
// 年と日は使わない
(_, int month, _) = DateTime.Now;

// 解析結果だけ取得し、変換された値は使わない
bool isNumeric = int.TryParse(str, out _);

switch (obj) {
    // string型で分岐するが、値は使わない
    case string _:
        // Do something.
        break;
}
```


#### ref戻り値、ref変数
`ref`キーワードの使用方法が拡張された。これによって、安全な参照の使い道が広がった。

##### ref戻り値
戻り値の型を`ref`で修飾することで、オブジェクトの参照を戻り値とすることができる。


```csharp
// 二つの参照引数の内、値の大きいものの参照戻り値を返す
static ref int Max(ref int left, ref int right) {
    if (left >= right) {
        return ref left;
    }
    else {
        return ref right;
    }
}
```


変数の寿命は変わらないため、メソッド終了時に破棄されるローカル変数をref戻り値とすることはできない。


```csharp
static int s_count = 1;

// メンバーの参照はref戻り値になる。
static ref int ReturnMember() {
    return ref s_count;
}
// ref引数はもちろんref戻り値になる。
static ref int ReturnRefParam(ref int something) {
    return ref something;
}
// ローカル変数をref戻り値とすることはできない。
// static ref int ReturnLocal() {
//     int x = 1;
//     return ref x;
// }
```


##### ref変数
ローカル変数の型を`ref`で修飾することで、参照を代入することができる。


```csharp
// 参照戻り値を参照変数で受け取る
ref int max = ref Max(ref x, ref y);
// limitとmaxは同じ値を参照する
ref int limit = ref max;
```


### C# 7.1からの仕様
#### 非同期なMainメソッド
Mainメソッドの戻り値として、`Task`型、`Task(int)`型が認められた。

```csharp
static Task Main()
```


```csharp
static Task<int> Main()
```

#### default式
型推論可能な場面では、`default`の型指定は省略可能となった。

```csharp
int number = default;
string name = default;
```


### C# 7.2からの仕様
C#7.2で追加された仕様は以下の通り。

#### 値型の参照セマンティクス
値型におけるパフォーマンス向上を意図した複数の機能が追加された。

##### in参照渡し、ref readonly参照戻り値
引数に`in`を指定することで、読み取り専用参照渡しを指定できる。また、戻り値に`ref readonly`を指定することで、読み取り専用参照戻り値を指定できる。

これにより、構造体のコピーを避けると共に、意図しない値の変更を抑止できる。

##### readonly構造体
構造体宣言時に`readonly`を指定することで、真の読み取り専用構造体を定義できる。readonly構造体の全てのフィールドは`readonly`でなければならず、`this`ポインタも読み取り専用となる。

これにより、メンバーアクセス時の意図しない防御的コピーを抑止できる。

##### ref構造体
構造体宣言時に`ref`を指定することで、ヒープ領域へのコピーを防ぐ構造体がサポートされる。ref構造体では、box化できない、配列を作成できない、型引数になることができない、など、ヒープ領域へのコピーを防ぐための厳しい制限がかかる。

この機能は、`Span<T>`のような構造体をサポートするために利用され、unsafe文脈以外での`stackalloc`の利用をも可能とする。

#### 末尾以外の場所での名前付き引数
C#4.0で追加された名前付き引数が末尾以外でも利用できるようになった。


```csharp
Hogehoge(name: "John", 17);
```


#### private protected アクセス修飾子
同一アセンブリ内、かつ、継承先からのアクセス許可を表す`private protected`アクセス修飾子が追加された。

#### 数値リテラルの改善
十六進リテラルの`0x`、二進リテラルの`0b`の直後のアンダースコアが認められた。


```csharp
int bin = 0b_01_01;
int hex = 0x_AB_CD;
```


### C# 7.3からの仕様
C#7.3では以下の仕様が追加された。

* ジェネリック型制約の種類の追加
** `System.Enum`、`System.Delegate`
** `unmanaged`（文脈キーワード）


```csharp
unsafe class MyGenericsClass<T1,T2,T3> 
    where T1 : System.Enum
    where T2 : System.Delegate
    where T3 : unmanaged {

    public MyGenericsClass(T1 enum1, T1 enum2, T2 func, T3 unmanagedValue) {
        if (enum1.HasFlag(enum2)) {
            func.DynamicInvoke();
        }
        else {
            T3* ptr = &unmanagedValue;
        }
    }
}
```


* `ref`ローカル変数の再割り当て
* `stackalloc`初期化子
* Indexing movable fixed buffers
* カスタム`fixed`ステートメント
* オーバーロード解決ルールの改善
* 出力変数宣言の利用箇所の追加


```csharp
class MyOutVar {
    // メンバー変数初期化子やコンストラクタ初期化子で出力変数宣言が可能
    readonly int x = int.TryParse("123", out var number) ? number : -1;
}
```


* タプル同士の比較


```csharp
(long, long) tuple = (1L, 2L);
// タプルのすべての要素間で == が比較可能
if (tuple == (1, 2)) { }
// 要素数が異なるタプル同士は比較できない。
//if (tuple == (1, 2, 3)) { }
```


* バッキングフィールドに対するAttribute指定


```csharp
// C#7.2までは無効な指定(コンパイル自体は可能。無視される)
// C#7.3からはバッキングフィールドに対するAttribute指定と見なされる
[field: NonSerialized]
public int MyProperty { get; set; }
```


### C# 8.0からの仕様

C# 8.0で追加された仕様は以下の通り。

#### null許容参照型

参照型にnull許容性を指定できるようになった。参照型の型名に`?`を付加した場合にnull許容参照型となる。

参照型の型名に`?`を付加しない場合、null非許容参照型となる。

フロー解析レベルでのnull許容性チェックが行われる。null許容値型の`Nullable<T>`のような新しい型は導入されない。

##### null許容コンテキスト

参照型のnull許容性は、null許容コンテキストによって有効、無効の切り替えが可能である。C#7.3以前の互換性のために、既定では無効となっている。

* Nullable コンパイルオプション： プロジェクト全体でのnull許容コンテキストを指定する
* `#nullable` ディレクティブ： ソースコードの部分ごとにnull許容コンテキストを指定する
** `annotations` オプション、`warnings`オプションにより、適用範囲を限定できる

##### null免除演算子

null許容参照型の変数名の後に `!`を使用することで、フロー解析時の警告が免除される。

#### インタフェースの既定メンバー

インタフェースのメンバーに既定の実装を指定できるようになった。また、インタフェースに静的メンバーを持つことができるようになった。

さらに、インタフェースのメンバーにアクセシビリティを指定できるようになった。

* 既定のアクセシビリティは、従来通り `public` となる。
* 実装があるインスタンスメンバーは、既定で `virtual` となり `override`可能である。
* 実装を`override`させないために`sealed`を指定することができる。

#### パターンマッチングの拡張 (C# 8.0)

`switch`式が追加された。プロパティパターン、タプルパターン、位置指定パターンの追加により、再帰的なパターンマッチングが可能になった。

* switch式
* 再帰パターン
** プロパティパターン
** タプルパターン
** 位置指定パターン

#### 非同期ストリーム

`IAsyncEnumerable<T>`インタフェースを返すことで、イテレータ構文と非同期構文の共存が可能になった。


```csharp
async IAsyncEnumerable<int> EnumerateAsync() {
    await Task.Delay(100);
    yield return 1;
    await Task.Delay(100);
    yield return 2;
}
```


`await foreach`によって非同期ストリームを列挙する。


```csharp
async void SpendAsync() {
    await foreach (var item in EnumerateAsync()) {
        Console.WriteLine(item);
    }
}
```


#### 範囲指定

`Index`と`Range`を指定できる専用構文が追加された。


```csharp
Index a = 1; // new Index(1, fromEnd: false)
  Index b = ^1; // new Index(1, fromEnd: true)
  Range range = a..b; // new Range(start: a, end: b)
```


#### その他の仕様

* 静的ローカル関数
* null結合代入演算子
* 構造体の読み取り専用メンバー
* using 宣言
* ref構造体のDispose
* ジェネリクスを含むアンマネージ型
* 式中の`stackalloc`
* 文字列補間のトークン順序の緩和

### C# 9.0からの仕様

C# 9.0で追加された仕様は以下の通り。

* レコード
* プロパティのinitアクセサ
* 最上位レベルステートメント
* パターンマッチングの拡張
* new式の型推論
* 条件演算子の型推論
* 共変戻り値
* GetEnumeratorの拡張メソッド対応
* 静的匿名関数
* ラムダ式引数の破棄
* ローカル関数への属性適用
* パフォーマンスと相互運用
** ネイティブサイズの整数型（`nint`型、`nuint`型）
** 関数ポインタ（`delegate*`型）
** 変数初期化フラグの抑制
* コードジェネレータのサポート
** モジュール初期化子
** 部分メソッドの拡張
### C# 10.0からの仕様

C# 10.0で追加された仕様は以下の通り。

* レコード構造体
* 構造体型の機能強化
* 補間された文字列ハンドラー
* global using ディレクティブ
* ファイル スコープの名前空間の宣言
* 拡張プロパティのパターン
* ラムダ式の機能強化
* const 補間文字列を許可する
* レコードの型で ToString() を封印できる
* 限定代入の機能強化
* 同じ分解で代入と宣言の両方を許可する
* メソッドで AsyncMethodBuilder 属性を許可する
* CallerArgumentExpression 属性
* 拡張 #line pragma
* 警告ウェーブ 6

### C# 11.0からの仕様
C# 11.0で追加された仕様は以下の通り。

#### 生文字列リテラル
エスケープなどの加工を施さない生の文字列を、3個以上の二重引用符で括る事で表現できる様になった。**未加工の文字列リテラル**とも呼ばれる。生文字列中には、その文字列を括っている二重引用符より少ない数で連続した二重引用符を普通の文字として埋め込む事ができる。文字列の開始を示す二重引用符の直後に何らかの文字列が記述されているかどうかで単一行か複数行かが弁別される。

単一行の場合は、`"""あいうえお"かきくけこ"さしすせそ"""`の様に記述でき、これはを表す。文字列中に3個の二重引用符を含める場合は`""""たちつてと"""なにぬねの""""`などと書ける。

複数行の場合において開始を示す二重引用符の直後は、空白または改行のみが受け付けられ、次の行が実際の一行目となる。複数行の生文字列の行はインデントする事ができ、文字列の終了を示す二重引用符のインデント位置と同等の空白文字とタブ文字が全ての行から削除される。その為、終了を示す二重引用符は、最終行の次の行にインデントと伴に置かなければならず、途中の行をこのインデント位置より浅くするとコンパイルエラーになる。

複数行の生文字列の記述例は次の通り。

```csharp
string logMsg = """
	原因不明のエラーが発生しました。
	詳細はログファイル "C:\Logs\exception.log" を確認してください。
	""";
```


開始を示す二重引用符の直前に任意の数の`$`を置く事で、補間文字列の機能を用いる事もできる。式を埋め込むには`$`と同数の半角波括弧（`{`と`}`）で括らなければならない。`$`より少ない数で連続した波括弧は普通の文字として扱われ、`$`より多い数で連続させるとコンパイルエラーになる。

#### 汎用属性
属性の型が型引数を持てる様になった。

```csharp
// 属性
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class ConverterContractAttribute<TFrom, TTo> : Attribute { }

// 使用例
[ConverterContract<byte, string>()]
[ConverterContract<sbyte, string>()]
[ConverterContract<short, string>()]
[ConverterContract<ushort, string>()]
[ConverterContract<int, string>()]
[ConverterContract<uint, string>()]
[ConverterContract<long, string>()]
[ConverterContract<ulong, string>()]
public class IntToStringConverter
{
	// ...
}
```


#### パターンマッチングの拡張 (C# 11.0)
リストや配列に対するパターンマッチが可能になった。

```csharp
int[] nums = new[] { 0, 1, 2, 3, 4, 5 };

if (nums is [ 0, 1, 2, .. ]) {
	Console.WriteLine("配列は 0, 1, 2 から始まります。");
} else {
	Console.WriteLine("配列は 0, 1, 2 から始まりません。");
}
```

また、`Span&lt;char&gt;`や`ReadOnlySpan&lt;char&gt;`に対して文字列を用いたパターンマッチが可能になった。

```csharp
bool CheckSignature(ReadOnlySpan<char> sig)
	=> sig is "HOGE";
```


#### ジェネリック型数値演算
型引数に「数値型または数値型に類似している型」である事を示す制約を付け加える機能が導入された。また、それに呼応して下記の変更が行われた。
*明示的な論理シフト演算子（`&gt;&gt;&gt;`演算子）が追加された。
*シフト演算子の右側の引数の型に対する制限の撤廃され、`int`型以外の型を指定できる様になった。
*`checked`演算子のオーバーロードができる様になった。
*インターフェースのメソッドに対して`static abstract`キーワード（静的抽象）と`static virtual`キーワード（静的仮想）を指定できる様になった。
*インターフェース内に演算子を定義できる様になった。
ジェネリック型数値演算を用いた一例を下記に示す。

```csharp
// 大抵の演算子インターフェイスは System.Numerics 内に実装されている。
using System.Numerics;

// 任意の型に対して加算を行う事ができる関数。
static T MyAdd<T>(T value1, T value2)
	where T: IAdditionOperators<T, T, T> // 加算が可能な型のみを受け付ける制約。
	=> value1 + value2; // + 演算子を使う事ができる。

// 上記の関数定義のみで、下記の様に加算演算が定義された型であれば、任意の型で呼び出す事ができる。
int    a = MyAdd(  123,   456); // 結果：579
ulong  b = MyAdd(111UL, 222UL); // 結果：333
double c = MyAdd( 1.5D,  2.1D); // 結果：3.6
```


#### その他の仕様
* UTF-8 文字列リテラル
* 文字列補間式の改行
* ファイルローカル型
* 必須メンバー
* auto-default 構造体（構造体の未初期化のフィールド変数が自動的に既定値に初期化される）
* `nameof`のスコープ拡張
* `IntPtr`に別名 `nint`、`UIntPtr`に別名 `nuint`が付いた
* `ref`フィールド
* `scoped ref`変数
* メソッドグループからデリゲートへの変換の改善
* 警告ウェーブ 7

### C# 12.0からの仕様
C# 12.0で追加された仕様は以下の通り。

#### クラスと構造体のプライマリコンストラクター

レコード型（`record`）以外のクラス（`class`）と構造体（`struct`）でプライマリコンストラクターが使えるようになった。


```csharp
class Example(string message) 
{
    public string Message { get; } = message;
}
```


#### コレクション式

配列、コレクション、`Span<T>`などの初期化の記法が共通の記法（`[]`）で書けるようになった。


```csharp
// Create an array:
int[] a = [1, 2, 3, 4, 5, 6, 7, 8];

// Create a list:
List<string> b = ["one", "two", "three"];

// Create a span
Span<char> c  = ['a', 'b', 'c', 'd', 'e', 'f', 'h', 'i'];
```


#### スプレッド演算子

コレクション式で複数のコレクションをインライン展開できる新しい演算子（`..`）が追加された。


```csharp
int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
// 1, 2, 3, 4, 5, 6, 7, 8, 9,
int[] single = [.. row0, .. row1, .. row2];
```


#### その他の仕様
* インライン配列 
* 既定のラムダパラメーター
* 任意の型の別名設定
* `ref readonly`パラメーター
* 試験段階の属性
* インターセプター

### C# 13.0からの仕様
C# 13.0で追加された仕様は以下の通り。

#### 新しいエスケープシーケンス
エスケープ文字を表すエスケープシーケンスとして`\e`が追加された。これに従って`\x1b`の使用は非推奨となった。

#### 暗黙的なインデックスアクセス
オブジェクト初期化子においても`^`演算子を用いたアクセスが可能となった。これにより、初期化子内でも配列やリストなどの末尾から値へアクセスできる。

#### <code>params</code> コレクション
コレクション式に対応している型であれば、引数に`params`修飾子を付けられる様になった。


```csharp
// 関数定義
void Print(string format, params IEnumerable<object> args)
{
    /* ... 任意の実装 ... */

    // 例えば
    Console.WriteLine(format, args.ToArray());
}

// 呼び出し
int a = 2, b = 3;
Print("{0} + {1} = {2}", a, b, a + b);
```


#### 部分プロパティ
プロパティとインデクサにも`partial`修飾子の指定が可能となった。


```csharp
public partial bool IsThisPartialProperty { get; }

public partial char this[int index] { get; }
```


#### <code>Lock</code> クラスに対する <code>lock</code>
任意のオブジェクトで排他制御される問題への対策として、`lock`文専用の`Lock`クラスが用意された。以下の様に使う。


```csharp
var lockObj = new Lock();

lock (lockObj) {
    // 排他制御されるコード
}

// このコードは、コンパイラによって次の形に展開される：
using (lockObj.EnterScope()) {
    // 排他制御されるコード
}
```


#### その他の仕様
* メソッド グループでの自然型
* `ref` 構造体のインターフェイス実装
* `OverloadResolutionPriority` 属性（オーバーロードの解決優先度を変更できる）
* イテレーター・非同期メソッド内の `ref`/`unsafe`
* インターセプター
* コレクション式の改善

### C# 14.0からの仕様
C# 14.0で追加された仕様は以下の通り。

#### 拡張メンバー
新たに `extension` ブロックが導入され、拡張プロパティと拡張インデクサーを実装できる様になった。この機能は、**拡張メンバー**（英: ）または**拡張宣言**（英: ）などと呼称される。特定の型に対してメンバーを外部の型から後付する事ができる。型引数を受け取るには、`extension` キーワードの後ろに `&lt;T&gt;` と記述する。また、動的メンバーだけではなく静的メンバーを追加する事もできる。

整数型に新たなプロパティを追加するコードを以下に示す。

```csharp
static class Some
{
    extension(int arg)
    {
        public int Twice => arg << 1;
        public int Half  => arg >> 1;
    }
}
```


#### プロパティにおける <code>field</code> キーワード
プロパティのアクセサー内で `field` キーワードを用いる事でバッキングフィールドを自動生成できる。従ってプロパティ専用の変数を新たに定義する必要は無い。既に `field` という名称の変数が存在する場合、代わりに `@field` または `this.field` と記述しなければならない。

`get` アクセサーのみで用いる場合は以下の様に記述できる。

```csharp
class Some
{
    public object? Data { get => field ?? new(); set; }
}
```


対して、`set` アクセサーのみで用いる場合は以下の様に記述できる。

```csharp
class Some
{
    public int Number { get; set => value = field + 1; }
}
```


両方のアクセサーで同時に用いる事も、`set` の代わりに `init` 内で用いる事も、従来通り `get; set;` と記述する事もできる。バッキングフィールドに属性を付与する場合は、プロパティ宣言の直前に `[field: AttributeClassName()]` と記述する。

#### <code>null</code> 条件付き割り当て
`null` 条件演算子を代入演算子の左辺でも用いられる様になった。

例えば、次の様なクラスが定義されているものとする。

```csharp
class Some
{
    public string? Name { get; set; }
}
```


通常は、`if` 文を用いて `null` ではない場合にのみ代入処理が実施される様にしなければならない。

```csharp
void SetName(Some? obj, string? name)
{
    if (obj is not null) {
        obj.Name = name;
    }
}
```


新しい演算子によって、変数の検証を略記できる様になった。

```csharp
void SetName(Some? obj, string? name)
{
    obj?.Name = name;
}
```


#### 複合代入演算子のユーザー定義
複合代入演算子の動作を上書きできる様になった。コピーコストの削減が目的である。他の演算子と同じ書式で定義できる。


```csharp
public void operator +=(int arg) { /* ... ここに具体的なコードを書く ... */ }
```


#### その他の仕様
* `nameof` の拡張（引数無しのジェネリック型にも対応）
* 暗黙的な `Span<T>` と `ReadOnlySpan<T>` の変換
* ラムダ式の引数の修飾子（主に参照渡し関係）
* `partial` の拡張（部分コンストラクタと部分イベント）
* ファイルベースのアプリ・無視ディレクティブ（`[[シバン (Unix)|#!]]` と `#:`）

## 実装
C#の言語仕様は標準化団体Ecma Internationalを通じて公開・標準化されており、第三者がマイクロソフトとは無関係にコンパイラや実行環境を実装することができる。

### コンパイラの実装
* マイクロソフト製
** Visual Studio 2015 以降で使用されている、（コードネーム**[[Roslyn]]**）。ApacheライセンスのオープンソースプロジェクトでGitHubで公開されている。Windows、macOS、Linuxで動作する。C#のコンパイラはC#、VB.NETのコンパイラはVB.NETで実装されている。以前のコンパイラと比べて、リファクタリングやIDE、スクリプティングなどへの利用が可能なAPIが公開されており、コンパイラ以外への様々な応用が可能。
** Visual Studio 2013 まで使われていた、マイクロソフトによるVisual C# コンパイラ。
** 2006年のC# 2.0当時の、マイクロソフトによるShared Source Common Language Infrastructure。共通言語基盤（CLI）とC#コンパイラがソースコードで公開されている。
* Mono ProjectによるMono内の Mono Compiler Suite (mcs)。
* 2012年まで開発されていた、DotGNU ProjectによるPortable.NET内の the C-Sharp code compiler (cscc)。

### 実行環境の実装

* マイクロソフト
** .NET Runtime
** .NET Framework Runtime
* Mono Project
** Monoランタイム
* カプコン
** RE ENGINEに実装されている REVM

## 名称
ECMA-334 3rd/4th/5th edition によると、**C#** は「**C Sharp**（シーシャープ）」と発音し、**LATIN CAPITAL LETTER C (U+0043)**の後に **NUMBER SIGN # (U+0023)**と書く。MUSIC SHARP SIGN ♯ (U+266F) ではなく NUMBER SIGN # (U+0023)を採用したのは、フォントやブラウザなどの技術的な制約に加え、ASCIIコードおよび標準的キーボードには前者の記号が存在しないためである。

「#」を接尾辞とする名称は、他の .NET 言語にも使用されており、J#（Javaのマイクロソフトによる実装）、（Adaから）、F#（System Fなどから）が含まれる。更には、Gtk#（GTK などの GNOME ライブラリの .NET ラッパ）、（Cocoa のラッパ）などのライブラリにも使用されている。そのほか、SharpDevelopなどの「Sharp」を冠する関連ソフトウェアも存在する。

C# という名称の解釈として、「（A-Gで表された）直前の音を半音上げる」という音楽記号の役割に着目し、「C言語を改良したもの」を意味したのではないか、。これは、C++の名称が「C言語を1つ進めたもの」という意味でつけられたことにも似ている。アンダース・ヘルスバーグは、「C#」が「C++++」（すなわち「C++ をさらに進めたもの」）にみえるのが由来である、と語っている。

## 脚注
### 注釈

### 出典
#### 公式発表

#### 個人サイト

#### その他

## 参考文献
* 
* 

## 関連項目
* 言語仕様
** 
** C#のデータ型
** キーワード (C#)
* 実行環境
** .NET  (旧：.NET Core)
** .NET Framework
** Mono
** Xamarin
* 開発環境
** Visual Studio
*** Visual C#
** Visual Studio Code
**  - ジェットブレインズ社の.NET向け統合開発環境
** MonoDevelop  - OSSの統合開発環境
*** Xamarin Studio
*** Visual Studio for Mac
** SharpDevelop - フリーの統合開発環境
* 比較
** C#とJavaの比較

## 外部リンク
* C# 関連のドキュメント - はじめに、チュートリアル、リファレンス。 | Microsoft Docs - 公式ウェブサイト（日本語）
* 言語仕様
** Introduction - C# language specification | Microsoft Learn - C# 言語仕様、Microsoft Docs
** ECMA-334 - Ecma International ECMA-334 C# 言語仕様
** 
* C# Compiler | Mono Mono C# コンパイラ