Movatterモバイル変換


[0]ホーム

URL:


コンテンツにスキップ
Wikipedia
検索

C Sharp

出典: フリー百科事典『ウィキペディア(Wikipedia)』
曖昧さ回避この項目では、プログラミング言語について説明しています。音名のC♯については「嬰ハ」をご覧ください。
本来の表記は「C#」です。この記事に付けられたページ名は技術的な制限または記事名の制約により不正確なものとなっています。
C#
C#
C#のロゴ
パラダイム構造化プログラミング命令型プログラミングオブジェクト指向プログラミングイベント駆動型プログラミング関数型プログラミングジェネリックプログラミングリフレクションクラスベース、正格プログラミング、マルチパラダイムプログラミング ウィキデータを編集
登場時期2000年 (26年前) (2000)
設計者マイクロソフトアンダース・ヘルスバーグ率いるチーム)
開発者マイクロソフト ウィキデータを編集
最新リリース14.0/2025年11月11日 (3か月前) (2025-11-11)[a 1]
型付け強い静的型付け(4.0から動的型導入)
主な処理系CLR,Mono
影響を受けた言語C++C言語Java、Delphi、Modula-3EiffelF SharpHaskellIconJ SharpMicrosoft Visual J++Object PascalRustMLVisual Basic ウィキデータを編集
影響を与えた言語D言語,F#,Java,Nemerle,Vala,TypeScript
プラットフォームWindows,macOS,Linuxなど
ライセンスApacheライセンス (Roslyn)
ウェブサイトdocs.microsoft.com/ja-jp/dotnet/csharp/ウィキデータを編集
拡張子cs、csx ウィキデータを編集
テンプレートを表示

プログラミング言語

カテゴリ /テンプレート

C#(シーシャープ)は、マイクロソフト.NET向けに開発した汎用プログラミング言語であり[1]ECMAおよびISO標準化されている。C系言語やJavaに影響を受けた構文を持ち、Windowsを含む複数のプラットフォームで利用され、デスクトップWebクラウド、モバイル、ゲーム開発などに用いられる。

概要

[編集]

開発にはボーランドのTurbo PascalDelphiを開発したアンダース・ヘルスバーグを筆頭として多数の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に持ち込もうとしたマイクロソフトとは異なり、その多くの[注釈 1]仕様を積極的に公開し、標準化機構に託して自由な利用を許す[注釈 2]など、同社の姿勢の変化があらわれている。

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

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

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

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

[編集]
バージョン言語仕様リリース時期[a 4].NETVisual Studio出典と注釈
ECMA[3][4]ISO/IECマイクロソフト公式発表個人サイトその他
1.0

ECMA-334:2003 (2002年12月)

ISO/IEC 23270:2003 (2003年4月)

CSharp Language Specification v1.0.doc2002年01月.NET Framework 1.0.NET (2002)[a 5]N/AN/A
  • 1.1
  • 1.2
csharp language specification v1.2.doc2003年04月.NET Framework 1.1.NET 2003[b 1]
2.0

ECMA-334:2006 (2006年6月)

ISO/IEC 23270:2006 (2006年9月)

csharp 2.0 specification_sept_2005.doc2005年11月
  • .NET Framework 2.0
  • .NET Framework 3.0
2005[b 2]
3.0N/ACSharp Language Specification.doc2007年11月
  • .NET Framework 2.0
  • .NET Framework 3.0
  • .NET Framework 3.5
2008N/A[注釈 3]
4.0N/A2010年04月.NET Framework 42010[b 3]N/A
5.0

ECMA-334:2017 (2017年12月)

ISO/IEC 23270:2018 (2018年12月)

C# Language Specification 5.02012年08月.NET Framework 4.5
  • 2012
  • 2013
[b 4]
6.0

ECMA-334:2022 (2022年6月)

N/AN/A2015年07月
  • .NET Framework 4.6
  • .NET Core 1.0
  • .NET Core 1.1
2015N/A[6]
7.0

ECMA-334:2023 (2023年12月)

ISO/IEC 20619:2023 (2023年9月)

2017年03月.NET Framework 4.72017 version 15.0[a 6][7]
7.1N/A2017年08月.NET Core 2.02017 version 15.3[a 5][a 7]N/A
7.22017年11月.NET Core 2.02017 version 15.5[a 5][a 8]
7.32018年05月
  • .NET Core 2.1
  • .NET Core 2.2
  • .NET Framework 4.8
2017 version 15.7[a 9][b 5]
8.0C# 8 のドラフト仕様2019年09月
  • .NET Core 3.0
  • .NET Core 3.1
2019 version 16.3[a 10]N/A[8]
9.0機能仕様2020年11月.NET 5.02019 version 16.8[a 11][a 12][注釈 4]
10.02021年12月
  • .NET 6.0
  • .NET 6.0.1
2022 version 17.0[a 13][a 14]
11.02022年11月08日.NET 7.02022 version 17.4[a 15][a 16][a 17][b 6]
12.02023年11月14日.NET 8.02022 version 17.8[a 18][a 19][a 20][a 21][b 7]
13.02024年11月12日.NET 9.02022 version 17.12[a 22][a 23][a 24][b 8]
14.02025年11月11日.NET 10.02026 version 18.0[a 25][a 26][a 1][a 27][b 9]

言語仕様

[編集]

さまざまな意味において[要追加記述]、基盤である共通言語基盤(CLI)の多くの機能を反映している言語であるといえる。C#にある組み込み型のほとんどは、共通言語基盤のフレームワークに実装されている値型と対応している。

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

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

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

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

Hello World

[編集]

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

Console.WriteLine("Hello World!");

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

usingSystem;namespaceWikipedia{classProgram{staticvoidMain(string[]args){Console.WriteLine("Hello World!");}}}

次の言語機能によって実現されている。ただし、未対応の古いコンパイラを用いる場合は、省略できない。

CやC++からの改良点

[編集]

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

構文や構文以外の改良点

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

ポインタとメモリ管理

[編集]
  • ポインタをサポートする。ポインタは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 Type)が導入された[a 5]。以下のようにクラスや構造体の宣言にpartial修飾子をつけることで、その宣言を分割することができる。

partialclassMyClass{inta;}partialclassMyClass{intb;}

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

classMyClass{inta;intb;}

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

ジェネリクス

[編集]
→「ジェネリックプログラミング § C#と.NETのジェネリックプログラミング」も参照

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

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

静的クラス

[編集]

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

yieldキーワード
[編集]

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

匿名デリゲート

[編集]

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

プロパティに対する個別のアクセス制御

[編集]

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

publicclassMyClass{privatestringstatus=string.Empty;publicstringStatus{get{returnstatus;}privateset{status=value;}}}

Null許容型とnull結合演算子

[編集]
→「Null合体演算子 § C#」も参照

nullを保持できる値型、Nullableが導入された[a 5]

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

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

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

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

objectobj1=null;objectobj2=newobject();objectobj3=newobject();returnobj1??obj2??obj3;// obj2 を返す

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

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

その他

[編集]

C# 3.0からの仕様

[編集]

varキーワード

[編集]

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

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

拡張メソッド

[編集]

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

publicstaticclassStringUtil{publicstaticstringRepeat(thisstringstr,intcount){vararray=newstring[count];for(vari=0;i<count;++i)array[i]=str;returnstring.Concat(array);}}

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

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

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

publicenumWay{None,Left,Right,Up,Down}publicstaticclassEnumUtil{publicstaticWayReverse(thisWaysrc){switch(src){caseWay.Left:returnWay.Right;caseWay.Right:returnWay.Left;caseWay.Up:returnWay.Down;caseWay.Down:returnWay.Up;default:returnWay.None;}}}

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

Wayl=Way.Left;Wayr=l.Reverse();// Way.Right

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

部分メソッド

[編集]

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

partialclassClass{partialvoidDebugOutput(stringmessage);voidMethod(){DebugOutput("Some message");Console.WriteLine("Did something.");}}

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

partialclassClass{partialvoidDebugOutput(stringmessage){Console.Write("[DEBUG: {0}] ",message);}}

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

ラムダ式

[編集]

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

以下の匿名メソッド

// iを変数としてi+1を返すメソッドdelegate(inti){returni+1;}

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

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

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

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

publicstaticstringToRPN(Expression<Func<int,int,int,int>>expression){returnParse((BinaryExpression)expression.Body).TrimEnd(' ');}privatestaticstringParse(BinaryExpressionexpr){stringstr="";if(expr.LeftisBinaryExpression){str+=Parse((BinaryExpression)expr.Left);}elseif(expr.LeftisParameterExpression){str+=((ParameterExpression)expr.Left).Name+" ";}elseif(expr.LeftisConstantExpression){str+=((ConstantExpression)expr.Left).Value+" ";}if(expr.RightisBinaryExpression){str+=Parse((BinaryExpression)expr.Right);}elseif(expr.RightisParameterExpression){str+=((ParameterExpression)expr.Right).Name+" ";}elseif(expr.RightisConstantExpression){str+=((ConstantExpression)expr.Right).Value+" ";}returnstr+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 / *" を返す

オブジェクト初期化の簡略化

[編集]

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

varp=newPoint{X=640,Y=480};// 上の文は次のように解釈される:Point__p=newPoint();__p.X=640;__p.Y=480;Pointp=__p;

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

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

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

自動実装プロパティ

[編集]

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

publicintValue{get;set;}

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

privateint__value;publicintValue{get{return__value;}set{__value=value;}}

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

匿名型

[編集]

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

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

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

publicstringName{get;}publicintAge{get;}

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

varher=new{Name="Jane Doe",Age=20}varhim=new{Name="John Doe",Age=20}

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

配列宣言の型省略

[編集]

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

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

クエリ式

[編集]

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

varpassedStudents=fromsinstudentswheres.MathScore+s.MusicScore+s.EnglishScore>200selects.Name;

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

varpassedStudents=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キーワードが導入され、動的型付け変数を定義できるようになった[a 5]。dynamic型として宣言されたオブジェクトに対する操作のバインドは実行時まで遅延される。

// xはint型と推論される:varx=1;// yはdynamic型として扱われる:dynamicy=2;publicdynamicGetValue(dynamicobj){// objにValueが定義されていなくとも、コンパイルエラーとはならない:returnobj.Value;}

オプション引数・名前付き引数

[編集]

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

publicvoidMethodA(){// 第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となっている}// 引数が指定されなかった場合のデフォルト値を等号で結ぶ:publicintMethodB(intA=0,intB=0,intC=0){returnA+B+C;}

ジェネリクスの共変性・反変性

[編集]

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

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

C# 5.0からの仕様

[編集]

C# 6.0からの仕様

[編集]
  • 自動実装プロパティの初期化子[a 37]
  • getのみの自動実装プロパティおよびコンストラクタ代入[a 37]
  • 静的usingディレクティブ[a 37]
  • インデックス初期化子[a 37]
  • catch/finallyでのawait[a 37]
  • 例外フィルタ[a 37]
  • 式形式のメンバー(expression-bodied members)[a 37]
  • null条件演算子[a 37]
  • 文字列補間(テンプレート文字列)[a 37]
  • nameof演算子[a 37]
  • #pragma
  • コレクションの初期化子での拡張メソッド[a 37]
  • オーバーロード解決の改善[a 37]

静的 using ディレクティブ

[編集]

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

usingstaticSystem.Math;// ↑ソースコードの上部で宣言classHogehoge{// System.Math.Pow() , System.Math.PI を修飾無しで呼び出すdoublearea=Pow(radius,2)*PI;}

例外フィルタ

[編集]

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

try{// ...}catch(AggregateExceptionex)when(ex.InnerExceptionisArgumentException){// ...}

C# 7.0からの仕様

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

出力変数宣言

[編集]

out引数で値を受け取る場合、その場所で変数宣言可能となった[a 38]

total+=int.TryParse("123",outvarnum)?num:0;

パターンマッチング

[編集]
is 式の拡張
[編集]

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

voidCheckAndSquare(objectobj){// objの型チェックと同時にnumに値を代入する。if(objisintnum&&num>=0){num=num*num;}else{num=0;}// if文の条件セクションは、ifの外側と同じスコープConsole.WriteLine(num);}
switch 文の拡張
[編集]

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

voidDecide(objectobj){switch(obj){caseintnumwhennum<0:Console.WriteLine($"{num}は負の数です。");break;caseintnum:Console.WriteLine($"{num}を二乗すると{num * num}です。");break;case"B":Console.WriteLine($"これはBです。");break;casestringstrwhenstr.StartsWith("H"):Console.WriteLine($"{str}はHから始まる文字列です。");break;casestringstr:Console.WriteLine($"{str}は文字列です。");break;casenull:Console.WriteLine($"nullです");break;default:Console.WriteLine("判別できませんでした");break;}}

タプル

[編集]

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

タプル記法
[編集]

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

// タプル記法(int,string)tuple=(123,"Apple");Console.WriteLine($"{tuple.Item1}個の{tuple.Item2}");
分解
[編集]

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

vartuple=(123,"Apple");// 分解(intquantity,stringname)=tuple;Console.WriteLine($"{quantity}個の{name}");

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

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

staticclassDateExt{publicstaticvoidDeconstruct(thisDateTimedateTime,outintyear,outintmonth,outintday){year=dateTime.Year;month=dateTime.Month;day=dateTime.Day;}}

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

// 分解(intyear,intmonth,intday)=DateTime.Now;

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

値の破棄

[編集]

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

// 年と日は使わない(_,intmonth,_)=DateTime.Now;// 解析結果だけ取得し、変換された値は使わないboolisNumeric=int.TryParse(str,out_);switch(obj){// string型で分岐するが、値は使わないcasestring_:// Do something.break;}

ref戻り値、ref変数

[編集]

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

ref戻り値
[編集]

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

// 二つの参照引数の内、値の大きいものの参照戻り値を返すstaticrefintMax(refintleft,refintright){if(left>=right){returnrefleft;}else{returnrefright;}}

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

staticints_count=1;// メンバーの参照はref戻り値になる。staticrefintReturnMember(){returnrefs_count;}// ref引数はもちろんref戻り値になる。staticrefintReturnRefParam(refintsomething){returnrefsomething;}// ローカル変数をref戻り値とすることはできない。// static ref int ReturnLocal() {//     int x = 1;//     return ref x;// }
ref変数
[編集]

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

// 参照戻り値を参照変数で受け取るrefintmax=refMax(refx,refy);// limitとmaxは同じ値を参照するrefintlimit=refmax;

C# 7.1からの仕様

[編集]

非同期なMainメソッド

[編集]

Mainメソッドの戻り値として、Task型、Task(int)型が認められた[a 40]

staticTaskMain()
staticTask<int>Main()

default式

[編集]

型推論可能な場面では、defaultの型指定は省略可能となった[a 40]

intnumber=default;stringname=default;

C# 7.2からの仕様

[編集]

C#7.2で追加された仕様は以下の通り[a 41][a 42]

値型の参照セマンティクス

[編集]

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

in参照渡し、ref readonly参照戻り値
[編集]

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

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

readonly構造体
[編集]

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

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

ref構造体
[編集]

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

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

末尾以外の場所での名前付き引数

[編集]

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

Hogehoge(name:"John",17);

private protected アクセス修飾子

[編集]

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

数値リテラルの改善

[編集]

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

intbin=0b_01_01;inthex=0x_AB_CD;

C# 7.3からの仕様

[編集]

C#7.3では以下の仕様が追加された[a 43]

  • ジェネリック型制約の種類の追加
    • System.EnumSystem.Delegate
    • unmanaged(文脈キーワード)
unsafeclassMyGenericsClass<T1,T2,T3>whereT1:System.EnumwhereT2:System.DelegatewhereT3:unmanaged{publicMyGenericsClass(T1enum1,T1enum2,T2func,T3unmanagedValue){if(enum1.HasFlag(enum2)){func.DynamicInvoke();}else{T3*ptr=&unmanagedValue;}}}
  • refローカル変数の再割り当て
  • stackalloc初期化子
  • Indexing movable fixed buffers
  • カスタムfixedステートメント
  • オーバーロード解決ルールの改善
  • 出力変数宣言の利用箇所の追加
classMyOutVar{// メンバー変数初期化子やコンストラクタ初期化子で出力変数宣言が可能readonlyintx=int.TryParse("123",outvarnumber)?number:-1;}
  • タプル同士の比較
(long,long)tuple=(1L,2L);// タプルのすべての要素間で == が比較可能if(tuple==(1,2)){}// 要素数が異なるタプル同士は比較できない。//if (tuple == (1, 2, 3)) { }
  • バッキングフィールドに対するAttribute指定
// C#7.2までは無効な指定(コンパイル自体は可能。無視される)// C#7.3からはバッキングフィールドに対するAttribute指定と見なされる[field: NonSerialized]publicintMyProperty{get;set;}

C# 8.0からの仕様

[編集]

C# 8.0で追加された仕様は以下の通り。[a 44][19]

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>インタフェースを返すことで、イテレータ構文と非同期構文の共存が可能になった。

asyncIAsyncEnumerable<int>EnumerateAsync(){awaitTask.Delay(100);yieldreturn1;awaitTask.Delay(100);yieldreturn2;}

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

asyncvoidSpendAsync(){awaitforeach(variteminEnumerateAsync()){Console.WriteLine(item);}}

範囲指定

[編集]

IndexRangeを指定できる専用構文が追加された。

Indexa=1;// new Index(1, fromEnd: false)Indexb=^1;// new Index(1, fromEnd: true)Rangerange=a..b;// new Range(start: a, end: b)

その他の仕様

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

C# 9.0からの仕様

[編集]

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

[a 45]

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

C# 10.0からの仕様

[編集]

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

[a 46]

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

C# 11.0からの仕様

[編集]

C# 11.0で追加された仕様は以下の通り[a 15][b 6]

生文字列リテラル

[編集]

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

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

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

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

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

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

汎用属性

[編集]

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

// 属性[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]publicclassConverterContractAttribute<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>()]publicclassIntToStringConverter{// ...}

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

[編集]

リストや配列に対するパターンマッチが可能になった[a 47][b 13]

int[]nums=new[]{0,1,2,3,4,5};if(numsis[0,1,2,..]){Console.WriteLine("配列は 0, 1, 2 から始まります。");}else{Console.WriteLine("配列は 0, 1, 2 から始まりません。");}

また、Span<char>ReadOnlySpan<char>に対して文字列を用いたパターンマッチが可能になった。

boolCheckSignature(ReadOnlySpan<char>sig)=>sigis"HOGE";

ジェネリック型数値演算

[編集]

型引数に「数値型または数値型に類似している型」である事を示す制約を付け加える機能が導入された[a 48][b 14]。また、それに呼応して下記の変更が行われた。

  • 明示的な論理シフト演算子(>>>演算子)が追加された。
  • シフト演算子の右側の引数の型に対する制限の撤廃され、int型以外の型を指定できる様になった。
  • checked演算子のオーバーロードができる様になった。
  • インターフェースのメソッドに対してstatic abstractキーワード(静的抽象)とstatic virtualキーワード(静的仮想)を指定できる様になった[a 49][a 50]
  • インターフェース内に演算子を定義できる様になった。

ジェネリック型数値演算を用いた一例を下記に示す[a 51][a 52]

// 大抵の演算子インターフェイスは System.Numerics 内に実装されている。usingSystem.Numerics;// 任意の型に対して加算を行う事ができる関数。staticTMyAdd<T>(Tvalue1,Tvalue2)whereT:IAdditionOperators<T,T,T>// 加算が可能な型のみを受け付ける制約。=>value1+value2;// + 演算子を使う事ができる。// 上記の関数定義のみで、下記の様に加算演算が定義された型であれば、任意の型で呼び出す事ができる。inta=MyAdd(123,456);// 結果:579ulongb=MyAdd(111UL,222UL);// 結果:333doublec=MyAdd(1.5D,2.1D);// 結果:3.6

その他の仕様

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

C# 12.0からの仕様

[編集]

C# 12.0で追加された仕様は以下の通り[a 18][b 7]

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

[編集]

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

classExample(stringmessage){publicstringMessage{get;}=message;}

コレクション式

[編集]

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

// Create an array:int[]a=[1,2,3,4,5,6,7,8];// Create a list:List<string>b=["one","two","three"];// Create a spanSpan<char>c=['a','b','c','d','e','f','h','i'];

スプレッド演算子

[編集]

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

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で追加された仕様は以下の通り[a 22][b 8]

新しいエスケープシーケンス

[編集]

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

暗黙的なインデックスアクセス

[編集]

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

params コレクション

[編集]

コレクション式に対応している型であれば、引数にparams修飾子を付けられる様になった[b 15]

// 関数定義voidPrint(stringformat,paramsIEnumerable<object>args){/* ... 任意の実装 ... */// 例えばConsole.WriteLine(format,args.ToArray());}// 呼び出しinta=2,b=3;Print("{0} + {1} = {2}",a,b,a+b);

部分プロパティ

[編集]

プロパティとインデクサにもpartial修飾子の指定が可能となった[a 53]

publicpartialboolIsThisPartialProperty{get;}publicpartialcharthis[intindex]{get;}

Lock クラスに対するlock

[編集]

任意のオブジェクトで排他制御される問題への対策として、lock文専用のLockクラスが用意された[b 16]。以下の様に使う。

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

その他の仕様

[編集]
  • メソッド グループでの自然型
  • ref 構造体のインターフェイス実装
  • OverloadResolutionPriority 属性(オーバーロードの解決優先度を変更できる)
  • イテレーター・非同期メソッド内のref/unsafe
  • インターセプター
  • コレクション式の改善

C# 14.0からの仕様

[編集]

C# 14.0で追加された仕様は以下の通り[a 25][b 9]

拡張メンバー

[編集]

新たにextension ブロックが導入され、拡張プロパティと拡張インデクサーを実装できる様になった[a 54][a 55]。この機能は、拡張メンバー[a 54]:extension members[a 56])または拡張宣言[a 57](英:extension declarations[a 58])などと呼称される。特定の型に対してメンバーを外部の型から後付する事ができる。型引数を受け取るには、extension キーワードの後ろに<T> と記述する。また、動的メンバーだけではなく静的メンバーを追加する事もできる。

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

staticclassSome{extension(intarg){publicintTwice=>arg<<1;publicintHalf=>arg>>1;}}

プロパティにおけるfield キーワード

[編集]

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

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

classSome{publicobject?Data{get=>field??new();set;}}

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

classSome{publicintNumber{get;set=>value=field+1;}}

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

null 条件付き割り当て

[編集]

null 条件演算子を代入演算子の左辺でも用いられる様になった[a 61][a 62]

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

classSome{publicstring?Name{get;set;}}

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

voidSetName(Some?obj,string?name){if(objisnotnull){obj.Name=name;}}

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

voidSetName(Some?obj,string?name){obj?.Name=name;}

複合代入演算子のユーザー定義

[編集]

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

publicvoidoperator+=(intarg){/* ... ここに具体的なコードを書く ... */}

その他の仕様

[編集]
  • nameof の拡張(引数無しのジェネリック型にも対応)
  • 暗黙的なSpan<T>ReadOnlySpan<T> の変換
  • ラムダ式の引数の修飾子(主に参照渡し関係)
  • partial の拡張(部分コンストラクタと部分イベント)

実装

[編集]

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

コンパイラの実装

[編集]
  • マイクロソフト製
    • Visual Studio 2015 以降で使用されている、.NETコンパイラプラットフォーム(コードネームRoslyn)。ApacheライセンスオープンソースプロジェクトでGitHubで公開されている[a 64]WindowsmacOSLinuxで動作する。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)。

実行環境の実装

[編集]

名称

[編集]

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

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

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

脚注

[編集]

注釈

[編集]
  1. ^全てではなく一部にプロプライエタリなコンポーネントもある。そのため、それに依存するものなど、後述のMonoなどで制限がある場合がある[2]
  2. ^「ECMA-334」、「ISO/IEC 23270:2003」、「JIS X 3015」として標準化している。
  3. ^.NET Framework 2.0と3.0はLINQを除く[5]
  4. ^C# 9.0 以降のマイクロソフトの仕様書は機能仕様にまとめられている。標準仕様ではなくマイクロソフト独自の仕様として扱われている。
  5. ^この機能はglobal using とも呼ばれる。
  6. ^Unicode符号位置U+001Bとなる文字。
  7. ^変数名だけではなく型名や関数名などにも用いる事ができる。
  8. ^クラスまたは構造体のメンバーを参照する場合のみ。

出典

[編集]

公式発表

[編集]
  1. ^abAnnouncing .NET 10” (英語). .NET Blog (2025年11月11日). 2025年11月12日閲覧。
  2. ^Visual Basic 言語の戦略 - Visual Basic”. Microsoft (2023年5月10日). 2023年12月23日閲覧。
  3. ^Visual Studio Code 用の C# 開発キット - Visual Studio Subscription”. Microsoft (2023年10月13日). 2023年12月23日閲覧。
  4. ^.NET および .NET Core の公式サポート ポリシー”. .NET (2025年9月9日). 2025年9月16日閲覧。
  5. ^abcdefghijklmnopqrstC# の歴史”. Microsoft Docs. 2019年12月12日閲覧。
  6. ^Visual Studio 2017 バージョン 15.0 リリース ノート”. Microsoft Learn. 2021年1月23日閲覧。
  7. ^Visual Studio 2017 15.3 Release Notes”. Microsoft Learn. 2018年11月12日閲覧。
  8. ^Visual Studio 2017 15.5 Release Notes”. Microsoft Learn. 2018年11月12日閲覧。
  9. ^Visual Studio 2017 15.7 Release Notes”. Microsoft Learn. 2018年8月24日閲覧。
  10. ^Visual Studio 2019 Release Notes”. Microsoft Learn. 2019年9月30日閲覧。
  11. ^Richard Lander (2020年11月10日). “Announcing .NET 5.0” (英語). .NET Blog. Microsoft. 2020年11月11日閲覧。
  12. ^Visual Studio 2019 Release Notes”. Microsoft Learn. 2020年11月10日閲覧。
  13. ^C# バージョン 10”. Microsoft Learn (2024年12月20日). 2025年9月16日閲覧。
  14. ^Visual Studio 2022 バージョン 17.0 リリース ノート”. Microsoft Learn (2025年1月22日). 2025年9月16日閲覧。
  15. ^abC# 11 の新機能”. Microsoft Learn. 2023年8月15日閲覧。
  16. ^.NET 7 is Available Today” (英語). .NET Blog. 2023年8月15日閲覧。
  17. ^Visual Studio 2022 バージョン 17.4 リリース ノート”. Microsoft Learn. 2023年8月15日閲覧。
  18. ^abC# 12 の新機能”. Microsoft Learn. 2023年12月19日閲覧。
  19. ^Announcing C# 12”. Microsoft (2023年11月14日). 2024年11月30日閲覧。
  20. ^Announcing .NET 8” (英語). .NET Blog. 2023年12月19日閲覧。
  21. ^Visual Studio 2022 バージョン 17.8 リリース ノート”. Microsoft Learn. 2023年12月19日閲覧。
  22. ^abC# 13 の新機能”. Microsoft Learn. 2024年11月30日閲覧。
  23. ^Announcing .NET 9” (英語). .NET Blog. 2024年11月30日閲覧。
  24. ^Visual Studio 2022 バージョン 17.12 リリース ノート”. Microsoft Learn. 2024年11月30日閲覧。
  25. ^abC# 14 の新機能”. Microsoft Learn (2025年9月17日). 2025年10月1日閲覧。
  26. ^.NET 10 の新機能”. Microsoft Learn (2025年9月9日). 2025年9月16日閲覧。
  27. ^Visual Studio 2026 リリース ノート - 11 月の更新プログラム 18.0.0”. Microsoft Learn (2025年11月24日). 2025年12月13日閲覧。
  28. ^Native AOT deployment overview - .NET”. Microsoft (2023年9月12日). 2023年12月23日閲覧。
  29. ^Hello World - C# の概要に関する対話型チュートリアル”. Microsoft. 2023年12月23日閲覧。
  30. ^チュートリアル: 学習しながらコードをビルドするために最上位レベルのステートメントを使用してアイデアを探索する”. Microsoft (2023年11月15日). 2024年11月30日閲覧。
  31. ^.NET プロジェクト SDK”. Microsoft (2024年10月22日). 2024年11月30日閲覧。
  32. ^2-2 変数と定数”. Microsoft Docs. 2018年11月11日閲覧。
  33. ^.NET での文字エンコード”. Microsoft Docs. 2018年11月11日閲覧。
  34. ^組み込みの参照型 - C# リファレンス - C#”. Microsoft (2023年5月10日). 2023年12月23日閲覧。
  35. ^null 許容型のボックス化 (C# プログラミング ガイド)” (pdf). Microsoft. 2008年6月2日閲覧。
  36. ^拡張メソッド (C# プログラミング ガイド)”. Microsoft Docs. 2018年11月10日閲覧。
  37. ^abcdefghijklC# 6 の新機能”. Microsoft Docs. 2019年12月12日閲覧。
  38. ^abcdeC# 7.0 の新機能”. Microsoft Docs. 2019年12月12日閲覧。
  39. ^switch (C# リファレンス)”. Microsoft Docs. 2017年9月10日閲覧。
  40. ^abC# 7.1 の新機能”. Microsoft Docs. 2019年12月12日閲覧。
  41. ^C# 7.2 の新機能”. Microsoft Docs. 2019年12月12日閲覧。
  42. ^Mads Torgersen (2017年11月15日). “Welcome to C# 7.2 and Span” (英語). .NET Blog. Microsoft. 2017年11月23日閲覧。
  43. ^C# 7.3 の新機能”. Microsoft Docs. 2019年12月12日閲覧。
  44. ^C# 8.0 の新機能”. Microsoft Docs. 2019年12月12日閲覧。
  45. ^What's new in C# 9.0”. Microsoft Docs. 2021年10月17日閲覧。
  46. ^What's new in C# 10.0”. Microsoft Docs. 2022年11月3日閲覧。
  47. ^リスト パターン”. Microsoft Learn. 2023年8月15日閲覧。
  48. ^ジェネリック型数値演算”. Microsoft Learn. 2024年5月30日閲覧。
  49. ^静的抽象および仮想メンバー”. Microsoft Learn. 2024年5月30日閲覧。
  50. ^チュートリアル: C# 11 の機能を調べる - インターフェイスの静的仮想メンバー”. Microsoft Learn. 2024年5月30日閲覧。
  51. ^IAdditionOperators<TSelf,TOther,TResult> インターフェイス”. Microsoft Learn. 2024年5月30日閲覧。
  52. ^runtime/src/libraries/System.Private.CoreLib/src/System/Numerics/IAdditionOperators.cs at 69dc5ec395749dc17434140881eb1414fc989c28 · dotnet/runtime” (英語). GitHub. Microsoft (2022年8月18日). 2024年10月16日閲覧。
  53. ^すべての部分プロパティとインデクサー - C# feature specifications”. Microsoft Learn. 2025年5月20日閲覧。
  54. ^ab拡張メンバー - C#”. Microsoft Learn (2025年9月17日). 2025年10月1日閲覧。
  55. ^拡張メンバー - C# feature specifications”. Microsoft Learn (2025年8月16日). 2025年10月1日閲覧。
  56. ^Extension members - C#” (英語). Microsoft Learn (2025年9月17日). 2025年10月1日閲覧。
  57. ^拡張メンバー宣言 - C# reference”. Microsoft Learn (2025年9月17日). 2025年10月1日閲覧。
  58. ^Extension member declarations - C# reference” (英語). Microsoft Learn (2025年9月18日). 2025年10月1日閲覧。
  59. ^'field' コンテキスト キーワード - C# reference”. Microsoft Learn (2025年8月16日). 2025年10月1日閲覧。
  60. ^「field」コンテキスト・キーワード - C# feature specifications”. Microsoft Learn (2025年8月16日). 2025年10月1日閲覧。
  61. ^メンバー アクセスと null 条件演算子と式: - C# reference”. Microsoft Learn (2025年5月31日). 2025年10月1日閲覧。
  62. ^Null 条件付き割り当て - C# feature specifications”. Microsoft Learn (2025年8月16日). 2025年10月1日閲覧。
  63. ^ユーザー定義の複合代入 - C# feature specifications”. Microsoft Learn (2025年8月16日). 2025年10月1日閲覧。
  64. ^dotnet/roslyn: The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.” (英語). GitHub. Microsoft (2022年11月29日). 2024年11月30日閲覧。

個人サイト

[編集]
  1. ^C# 1.0 - C# によるプログラミング入門”. ++C++; // 未確認飛行 C. 2021年1月23日閲覧。
  2. ^C# 2.0 の新機能 - C# によるプログラミング入門”. ++C++; // 未確認飛行 C. 2021年1月23日閲覧。
  3. ^C# 4.0 の新機能 - C# によるプログラミング入門”. ++C++; // 未確認飛行 C. 2021年1月23日閲覧。
  4. ^C# 5.0 の新機能 - C# によるプログラミング入門”. ++C++; // 未確認飛行 C. 2021年1月23日閲覧。
  5. ^C# 7.3 の新機能 - C# によるプログラミング入門”. ++C++; // 未確認飛行 C. 2021年1月23日閲覧。
  6. ^abC# 11.0 の新機能 - C# によるプログラミング入門”. ++C++; // 未確認飛行 C. 2023年8月15日閲覧。
  7. ^abC# 12.0 の新機能 - C# によるプログラミング入門”. ++C++; // 未確認飛行 C. 2023年12月19日閲覧。
  8. ^abC# 13.0 の新機能 - C# によるプログラミング入門”. ++C++; // 未確認飛行 C. 2024年11月30日閲覧。
  9. ^abC# 14.0 の新機能 - C# によるプログラミング入門”. ++C++; // 未確認飛行 C. 2025年10月1日閲覧。
  10. ^パターン マッチング - C# によるプログラミング入門”. 2023年12月23日閲覧。
  11. ^C# 9.0 の新機能 - C# によるプログラミング入門” (2020年5月9日). 2023年12月23日閲覧。
  12. ^abc生文字列リテラル”. ++C++; // 未確認飛行 C (2021年9月18日). 2025年12月14日閲覧。
  13. ^リスト パターン”. ++C++; // 未確認飛行 C. 2023年8月15日閲覧。
  14. ^【Generic Math】 C# 11 での演算子の新機能”. ++C++; // 未確認飛行 C. 2024年5月30日閲覧。
  15. ^可変長引数 - C# によるプログラミング入門”. ++C++; // 未確認飛行 C. 2025年1月9日閲覧。
  16. ^Lock クラス”. ++C++; // 未確認飛行 C. 2025年5月20日閲覧。
  17. ^複合代入演算子のオーバーロード”. ++C++; // 未確認飛行 C. 2025年10月1日閲覧。

その他

[編集]
  1. ^岩崎宰守「Microsoft、開発フレームワーク「.NET Core 1.0」「ASP.NET Core 1.0」「EF Core 1.0」を提供開始」『INTERNET Watch』2016年6月28日。2025年11月20日閲覧
  2. ^abAbel Avram (2009年7月29日). “誰でもC#とCLIの正式な実装が可能に”. InfoQ. 2019年12月2日閲覧。
  3. ^Standard ECMA-334”. ECMA. 2023年12月23日閲覧。
  4. ^Standard ECMA-334-archive”. 2018年11月13日時点のオリジナルよりアーカイブ。2018年11月13日閲覧。
  5. ^Using C# 3.0 from .NET 2.0”. Danielmoth.com (2007年5月13日). 2012年10月4日閲覧。
  6. ^“Microsoft、「.NET Framework 4.6」を正式公開”. 窓の杜. https://forest.watch.impress.co.jp/docs/news/712658.html 2021年1月23日閲覧。 
  7. ^“.NET Framework 4.7が一般公開される”. InfoQ. https://www.infoq.com/jp/news/2017/05/net47-released/ 2021年1月23日閲覧。 
  8. ^“Micorsoftが.NET Core 3.0をリリース”. InfoQ. https://www.infoq.com/jp/news/2019/12/microsoft-releases-dotnet-core-3/ 2021年1月23日閲覧。 
  9. ^IL2CPP の概要 - Unity マニュアル”. Unity. 2023年12月23日閲覧。
  10. ^Burst の概要”. Unity. 2023年12月23日閲覧。
  11. ^ab高橋 2005, p. 70.
  12. ^高橋 2005, pp. 63–64.
  13. ^高橋 2005, pp. 70, 71.
  14. ^高橋 2005, p. 68.
  15. ^高橋 2005, pp. 68–70.
  16. ^高橋 2005, pp. 66, 67.
  17. ^高橋 2005, p. 71.
  18. ^高橋 2005, p. 72.
  19. ^MicrosoftがC# 8.0をリリース”. InfoQ (2019年12月10日). 2019年12月12日閲覧。
  20. ^Tim Smith (2010年10月4日). “Javaと.NETの特許問題への短い紹介”. InfoQ. 2019年12月2日閲覧。
  21. ^ゲームプログラムのC#8.0/.NET対応とその未来”. CAPCOM. 2024年6月29日閲覧。
  22. ^Standard ECMA-334 C# Language Specification
  23. ^The A-Z of programming languages: F# | Network World
  24. ^レポート:コミュニティスペシャルセッション with Anders Hejlsberg in Microsoft Developers Conference 2006
  25. ^C#への期待。アンダースからの返答

参考文献

[編集]
  • 高橋 忍「C# 2.0の新しい言語仕様」『C MAGAZINE(2005年2月号)』第17巻第2号、ソフトバンク パブリッシング。 
  • 山田祥寛『独習C#』(第5版)翔泳社〈独習〉、2022年7月21日。ISBN 978-4-7981-7556-0 

関連項目

[編集]

外部リンク

[編集]
アーキテクチャ
共通言語基盤
言語
パッケージマネージャ
関連技術
その他のCLI実装
組織
開発環境
その他
カテゴリカテゴリ
コンピュータ・プログラミング言語
低水準言語
高水準言語
1950年代
1960年代
1970年代
1980年代
1990年代
2000年代
2010年代
2020年代
架空の言語
ISO標準
国際標準一覧 · ローマ字表記国際規格一覧 · 国際電気標準会議が定める国際標準一覧
1から
10000まで
10001から
20000まで
20001以上
組織
カテゴリ カテゴリ
関連項目:ISOで始まる記事一覧
国立図書館
その他
https://ja.wikipedia.org/w/index.php?title=C_Sharp&oldid=108418751」から取得
カテゴリ:
隠しカテゴリ:

[8]ページ先頭

©2009-2026 Movatter.jp