C# ( / ˌ siː ˈ ʃ ɑːrp / SHARPを参照) [ b ]は、複数のパラダイムをサポートする汎用的な高水準プログラミング言語です。C# は、静的型付け[ 17 ] : 4強力な型付け、字句スコープ、命令型、宣言型、関数型、ジェネリック型[ 17 ] : 22オブジェクト指向(クラスベース)、およびコンポーネント指向のプログラミング分野を包含しています。 [ 1 ]
C# プログラミング言語の主な設計者は、MicrosoftのAnders Hejlsberg、Scott Wiltamuth、および Peter Goldeでした。[ 1 ] 2000 年 7 月に初めて広く配布され[ 1 ] 、その後 2002 年にEcma (ECMA-334)、 2003 年にISO / IEC (ISO/IEC 23270 および 20619 [ c ] )によって国際標準として承認されました。Microsoft は、 .NET Frameworkおよび Microsoft Visual Studioとともに C# を発表しましたが、これらは技術的にはクローズド ソースです。当時、Microsoft にはオープンソース製品はありませんでした。4 年後の 2004 年に、C# プログラミング言語用のクロス プラットフォームコンパイラおよびランタイム環境を提供するMonoと呼ばれる無料のオープンソースプロジェクトが開始されました。 10年後、マイクロソフトはVisual Studio Code(コードエディタ)、Roslyn(コンパイラ)、そして統合プラットフォームである.NET(ソフトウェアフレームワーク)をリリースした。これらはすべてC#をサポートし、無料、オープンソース、クロスプラットフォームである。Monoもマイクロソフト傘下に入ったが、.NETには統合されなかった。
Ecma標準では、C#の設計目標として以下の項目が挙げられています。[ 1 ]
.NET Frameworkの開発中、クラスライブラリは当初、Simple Managed C (SMC)と呼ばれるマネージドコードコンパイラシステムを使用して記述されていました。 [ 23 ] [ 24 ] 1999 年 1 月、Anders Hejlsberg は、当時 COOL と呼ばれていた新しい言語を構築するためのチームを結成しました。COOL は「C ライクなオブジェクト指向言語」の略です。[ 25 ]
マイクロソフトは当初、「COOL(Cライクなオブジェクト指向言語)」という名称を言語の最終名称として採用することも検討したが、商標上の理由から断念した。2000年7月のプロフェッショナル・デベロッパーズ・カンファレンスで.NETプロジェクトが正式に発表された時点では、言語名はC#に変更され、クラスライブラリとASP.NETランタイムもC#に移植されていた。
ヘイルスバーグはマイクロソフトでC#の主任設計者兼主任アーキテクトを務め、以前はTurbo Pascal、Embarcadero Delphi(旧CodeGear Delphi、Inprise Delphi、Borland Delphi)、Visual J++の設計にも携わっていました。インタビューや技術論文の中で、彼はほとんどの主要なプログラミング言語(C++、Java、Delphi、Smalltalkなど)の欠陥が共通言語ランタイム(CLR)の基本を決定づけ、それがC#言語の設計を決定づけたと述べています。[ 26 ]
1994年にJavaプログラミング言語を作成したジェームズ・ゴスリングと、Javaの生みの親であるサン・マイクロシステムズの共同創設者ビル・ジョイは、C#をJavaの「模倣」と呼びました。ゴスリングはさらに、「C#は、信頼性、生産性、セキュリティが削除されたJavaのようなものです」と述べています。[ 27 ] [ 28 ]
2000年7月、ヘイルスバーグはC#は「Javaのクローンではない」し、その設計は「C++にずっと近い」と述べた。[ 29 ]
2005 年 11 月に C# 2.0 がリリースされて以来、C# と Java 言語はますます異なる軌道で進化し、まったく異なる 2 つの言語になりました。最初の大きな違いの 1 つは、両方の言語にジェネリクスが追加されたことですが、その実装は大きく異なります。C# は、他のクラスと同様に使用できる「第一級」のジェネリック オブジェクトを提供するために具体化を使用し、コード生成はクラス ロード時に実行されます。[ 30 ]
C# は、関数型プログラミングに対応するためにいくつかの主要な機能を追加しており、C# 3.0 でリリースされたLINQ拡張機能と、それを支えるラムダ式、拡張メソッド、匿名型などのフレームワークがその集大成となっています。[ 31 ]これらの機能により、C# プログラマーは、アプリケーションにとって有利な場合にクロージャなどの関数型プログラミング手法を使用できます。LINQ 拡張機能と関数インポートは、データベースのクエリ、XML ファイルの解析、データ構造の検索などの一般的なタスクに含まれる定型コードの量を削減し、実際のプログラムロジックに重点を置くことで、可読性と保守性を向上させるのに役立ちます。[ 32 ]
C#にはかつてAndy(Anders Hejlsbergにちなんで名付けられた)というマスコットがいた。2004年1月29日に引退した。[ 33 ]
C# は当初、ISO/IEC JTC 1 サブコミッティSC 22にISO/IEC 23270:2003 の下でレビューのために提出されました[ 34 ] [ 35 ]が、撤回され、その後 ISO/IEC 23270:2006 の下で承認されました[ 36 ] 23270:2006 は 23270:2018 の下で撤回され、このバージョンで承認されています[ 37 ] ]
マイクロソフトは1988年に、インクリメンタルコンパイル用に設計されたC言語の派生版に初めてC#という名前を使用しました。[ 38 ]そのプロジェクトは完了せず、その名前は後に再利用されました。
「C シャープ」という名前は、楽譜のシャープ記号が、書かれた音符を半音高くすることを示すことに由来しています。[ 39 ]これは、 C++ という言語名に似ており、「++」は変数が評価後に 1 ずつ増加することを示します。また、シャープ記号は4 つの「+」記号 (2 × 2 のグリッド) の合字に似ており、この言語が C++ の増分であることをさらに示唆しています。[ 40 ]
表示の技術的な制限(標準フォント、ブラウザなど)と、シャープ記号(U+266F ♯ミュージックシャープ記号(& sharp; ) )がないほとんどのキーボードレイアウトのため、プログラミング言語の表記名ではシャープ記号を近似するために数字記号(U+0023 #数字記号(& num; ))が選択されました。[ 41 ] この慣例は、ECMA-334 C# 言語仕様に反映されています。[ 1 ]
「シャープ」接尾辞は、J# ( Java 1.1から派生した Microsoft が設計した .NET 言語)、A# (Ada から派生)、関数型プログラミング言語 F# など、既存の言語の派生形である他の Microsoft .NET 互換/準拠言語で使用されています。[ 42 ] .NET用のEiffelの元の実装はEiffel #と呼ばれていましたが、[ 43 ]完全なEiffel言語がサポートされるようになったため、この名前は廃止されました。この接尾辞は、 Gtk# ( GTKおよびその他のGNOMEライブラリの.NETラッパー) やCocoa# ( Cocoaのラッパー)などのライブラリにも使用されています。
標準規格(C# 6から)のテキスト開発はGitHub上で行われています。C# 7 はEcma に提出され、2023 年 12 月に承認されました。2024 年 1 月現在、C# 8 の標準規格は承認された言語提案を参照しながら開発中です。
C#言語のコア構文は、C、Objective-C、C++、Javaなどの他のCスタイルの言語と類似しており、特に以下の点が挙げられます。
C#がC、C++、Javaと異なる主な特徴(特に明記されている場合)は以下のとおりです。
設計上、C# は基盤となる共通言語インフラストラクチャ (CLI)を最も直接的に反映するプログラミング言語です。 [ 73 ] そのほとんどの組み込み型は、CLI フレームワークによって実装された値型に対応しています。ただし、言語仕様ではコンパイラのコード生成要件は規定されていません。つまり、C# コンパイラが共通言語ランタイム(CLR) をターゲットにする必要があるとか、共通中間言語(CIL) を生成する必要があるとか、その他の特定の形式を生成する必要があるとは規定されていません。一部の C# コンパイラは、Objective-C、C、C++、アセンブリ、 Fortranの従来のコンパイラと同様に、マシン コードを生成することもできます。[ 74 ] [ 75 ]
C# は、キーワード を使用した強力な暗黙的型付け変数宣言var[ 17 ] : 470と、キーワード にコレクション初期化子を続けて記述した暗黙的型付け配列をサポートしています。 [ 17 ] : 80 [ 21 ] : 58new[]
その型システムは、2 つのファミリーに分かれています。組み込みの数値型やユーザー定義の構造体などの値型は、パラメーターとして使用されるときに自動的にコピーとして渡されます。一方、配列、クラスのインスタンス、文字列などの参照型は、それぞれのオブジェクトへのポインタのみを渡します。等価演算子の特別な処理と不変性のため、文字列は実際には値のように動作します。プログラマは、文字列をケースラベルとして使用することもできます。必要に応じて、値型は自動的にボックス化されます。[ 76 ]
C# は厳密なブール型データ型をサポートしています。やなどboolの条件を取るステートメントでは、ブール値に評価される型の式が必要です。 C++ にもブール型がありますが、整数との間で自由に変換でき、 などの式では、 がブール型に変換可能であるだけでよく、は int またはポインタにすることができます。 C# では、この「整数は真または偽を意味する」アプローチは許可されていません。これは、プログラマに正確に を返す式の使用を強制することで、(等価性の代わりに代入を使用するなど)といった特定の種類のプログラミングエラーを防ぐことができるためです。whileiftrueif (a)aaboolif (a = b)===
C# はC++ よりも型安全性が高いです。デフォルトで暗黙的に行われる型変換は、整数の拡大など、安全とみなされるものに限られます。これはコンパイル時、ジャストインタイムコンパイル時、そして場合によっては実行時にも強制されます。ブール値と整数の間、および列挙型メンバーと整数の間(リテラル 0 は任意の列挙型に暗黙的に変換可能)では、暗黙的な型変換は行われません。C++ のコピーコンストラクタや変換演算子はデフォルトで暗黙的に行われるのに対し、C# ではユーザー定義の型変換は明示的か暗黙的かを明示的に指定する必要があります。
C# は、ジェネリック型における共変性と反変性を明示的にサポートしています。 [ 17 ] : 144 [ 21 ] : 23一方、C++ は、仮想メソッドの戻り値の型のセマンティクスを通じて反変性をある程度サポートしています。
C#言語では、グローバル変数やグローバル関数は使用できません。すべてのメソッドとメンバはクラス内で宣言する必要があります。パブリッククラスの静的メンバは、グローバル変数やグローバル関数の代わりとして使用できます。
CやC++とは異なり、ローカル変数は囲んでいるブロックの変数を隠蔽することはできませんが、型レベルの名前を隠蔽することはできます。
メタプログラミングは、いくつかの方法で実現できます。
System.Reflection.Emit名前空間[ 79 ]には、実行時にメタデータとCIL(型、アセンブリなど)を出力するクラスが含まれています。C# のメソッドは、単なる値保持機能を持つフィールド(クラス変数またはインスタンス変数)とは異なり、関数として呼び出すことができるクラスのメンバーです。[ 82 ] C++やANSI Cなど、構文的に類似した他の言語と同様に、メソッドのシグネチャは、次の順序で構成される宣言です。任意のアクセシビリティ キーワード (など)、戻り値の型の明示的な指定 (など、または値が返されない場合はキーワード)、メソッドの名前、最後に、括弧で囲まれたコンマで区切られたパラメータ指定のシーケンス。各パラメータ指定は、パラメータの型、正式な名前、およびオプションで、何も指定されていない場合に使用されるデフォルト値で構成されます。他のほとんどの言語とは異なり、参照による呼び出しパラメータは、関数の定義と呼び出しサイトの両方でマークする必要があり、プログラマは と を選択できます。後者では、戻り時に確定値を持つ未初期化変数を渡すことができます。[ 83 ]さらに、プログラマは最後のパラメータにキーワードを適用することで、可変サイズの引数リストを指定できます。 [ 84 ]フィールドの値を返したり代入したりすることで取得または設定するだけのメソッドなど、特定の種類のメソッドは、明示的に完全なシグネチャを宣言する必要はありませんが、一般的には、クラスの定義にはそのメソッドの完全なシグネチャ宣言が含まれます。[ 85 ]privateintvoidrefoutparams
C++ と同様に、Java とは異なり、C# プログラマーは、サブクラスによるメソッドのオーバーライドvirtualを許可するためにスコープ修飾子キーワードを使用する必要があります。C++ とは異なり、プログラマーはこれを行う際にキーワードを明示的に指定する必要があります。[ 86 ]これは、関数のオーバーライドと新しいオーバーロード、つまり前者の実装の隠蔽との混同を避けるためです。後者を行うには、プログラマーはキーワードを指定する必要があります。[ 87 ]このキーワードは、個々のメソッドまたはクラス全体に対するさらなるオーバーライドを禁止するために使用できます。[ 88 ]overridenewsealed
C# の拡張メソッドを使用すると、プログラマは静的メソッドをクラスのメソッドテーブルにあるメソッドのように使用でき、プログラマは、その種類のオブジェクト(およびそれぞれの派生クラスのインスタンス)に存在するべきだと考えるインスタンスメソッドをクラスに仮想的に追加できます。[ 17 ] : 103–105 [ 21 ] : 202–203
この型はdynamic実行時メソッドバインディングを可能にし、JavaScriptのようなメソッド呼び出しと実行時オブジェクト合成を可能にする。[ 17 ]: 114-118
C# はキーワード を介して厳密に型指定された関数ポインタをサポートしていますdelegate。Qt フレームワークの擬似C ++シグナルとスロットと同様に、C# にはパブリッシュ/サブスクライブ スタイルのイベントに関するセマンティクスがありますが、C# ではデリゲートを使用します。フィールドとは異なり、event変数はインターフェースの一部になることができます。これは、変数が技術的には、呼び出されるデリゲートを追加および削除するための 2 つのデフォルト関数で構成されているためです。
synchronizedC# は、属性を介してJava のようなメソッド呼び出しを提供し、キーワードを介して相互排他ロック[MethodImpl(MethodImplOptions.Synchronized)]をサポートしています。lock
C# はプロパティを持つクラスをサポートしています。プロパティは、バッキングフィールドを持つ単純なアクセサ関数にすることも、任意のゲッター関数とセッター関数を実装することもできます。セッターがない場合、プロパティは読み取り専用になります。フィールドと同様に、クラスプロパティとインスタンスプロパティを設定できます。基となるメソッドは、他のメソッドと同様にvirtual、またはにすることができます。 [ 85 ]abstract
C# 3.0以降、自動実装プロパティのシンタックスシュガーが利用可能になりました[ 89 ]。アクセサ(ゲッター)とミューテーター(セッター)は、クラスの単一のフィールドに対する操作をカプセル化します。
AC#namespaceは Javapackageや C++と同じレベルのコード分離を提供しnamespace、ルールや機能も非常に似ていますpackage。名前空間は「using」構文でインポートできます。[ 90 ]
C# では、メモリ アドレス ポインタはunsafeと明示的にマークされたブロック内でのみ使用できます[ 91 ] 。unsafeコードを含むプログラムを実行するには、適切な権限が必要です。ほとんどのオブジェクト アクセスは、常に「生きている」オブジェクトを指すか、明確に定義されたnull値を持つ安全なオブジェクト参照を介して行われます。「死んだ」オブジェクト (ガベージ コレクションされたオブジェクト) や任意のメモリ ブロックへの参照を取得することは不可能です。unsafe ポインタは、クラス インスタンス、配列、文字列など、ガベージ コレクションの対象となるオブジェクトへの参照を含まない、管理されていない値型のインスタンスを指すことができます。unsafe とマークされていないコードは、System.IntPtr型を介してポインタを格納および操作することはできますが、ポインタを逆参照することはできません。
管理対象メモリは明示的に解放することはできません。代わりに、自動的にガベージコレクションされます。ガベージコレクションは、ほとんどの場合、不要になったメモリを解放する責任をプログラマから解放することで、メモリリークの問題を解決します。必要以上にオブジェクトへの参照を保持するコードは、依然として必要以上のメモリ使用量となる可能性がありますが、オブジェクトへの最後の参照が解放されると、メモリはガベージコレクションの対象となります。
プログラマーはさまざまな標準例外を利用できます。標準ライブラリのメソッドは、特定の状況でシステム例外を定期的にスローし、スローされる例外の範囲は通常ドキュメントに記載されています。カスタム例外クラスをクラスに定義することで、必要に応じて特定の状況での処理を実装できます。[ 92 ]
例外処理の構文は以下のとおりです。
try { // 何らかの処理} catch ( Exception ex ) { // エラーが発生した場合の処理 } finally { // エラーの発生に関わらず、常に実行される}これは通常「try-catch」コードブロックと呼ばれます。これは、「try」関数と「catch」関数がすべてのC#バージョンで使用およびアクセスできるためです。「finally」部分は省略できます。エラーの詳細を調べる必要がない場合は、(Exception ex)パラメーターも省略できます。また、さまざまな種類の例外を処理する複数の「catch」部分が存在する場合があります。[ 93 ]
C#にはチェック例外は存在しません(Javaとは対照的です)。これは、スケーラビリティとバージョン管理の問題に基づいた意図的な決定です。[ 94 ]
C++とは異なり、C#は多重継承をサポートしていませんが、クラスは任意の数の「インターフェース」(完全抽象クラス)を実装できます。これは、言語の主任設計者が複雑さを回避し、CLI全体のアーキテクチャ要件を簡素化するために下した設計上の決定です。
Javaと同様に、C#では、同じ名前で同じ型のパラメーターを同じ順序で受け取るメソッド(つまり、同じシグネチャを持つメソッド)を含む複数のインターフェースを実装する場合、すべてのインターフェースをカバーする単一のメソッドと、必要に応じて各インターフェース専用のメソッドの両方を使用できます。
C# は関数オーバーロード(別名アドホック多態性) も提供しており、同じ名前だがシグネチャが異なるメソッドを定義できます。[ 95 ] Java とは異なり、C# は演算子オーバーロードもサポートしています。[ 96 ]
バージョン 2.0 以降、C# はパラメトリック多態性、つまり任意の型パラメータまたは制約付き型パラメータを持つクラスを提供します。たとえば、型 の要素のみを格納できる可変サイズの配列などです。プログラマが型パラメータに指定できる制約には、次のようなものがあります。 は型 X (またはそこから派生した型) でなければならない、特定のインターフェイスを実装しなければならない、参照型でなければならない、値型でなければならない、パブリックな引数なしコンストラクタを実装しなければならない。これらのほとんどは組み合わせることができ、任意の数のインターフェイスを指定できます。[ 97 ] [ 98 ]List<T>T
C# は .NET Framework を介してLINQを利用できます。開発者は、オブジェクトにインターフェイスが実装されていれば、さまざまなデータソースに対してクエリを実行できます。これには、 XMLドキュメント、ADO.NETデータセット、SQLデータベースなどが含まれます。[ 99 ]IEnumerable<T>
C# でLINQ を使用すると、 IntelliSense のサポート、強力なフィルタリング機能、コンパイルエラーチェック機能による型安全性、さまざまなソースからのデータクエリの一貫性などの利点が得られます。[ 100 ] C# と LINQ で使用できるさまざまな言語構造があり、クエリ式、ラムダ式、匿名型、暗黙的に型付けされた変数、拡張メソッド、オブジェクト初期化子などがあります。[ 101 ]
LINQにはクエリ構文とメソッド構文の2つの構文があります。ただし、コンパイラはコンパイル時に常にクエリ構文をメソッド構文に変換します。[ 102 ]
System.Linqを使用します。var numbers = new int [] { 5 , 10 , 8 , 3 , 6 , 12 };// クエリ構文 (SELECT num FROM numbers WHERE num % 2 = 0 ORDER BY num) var numQuery1 = from num in numbers where num % 2 == 0 orderby num select num ;// メソッド構文var numQuery2 = numbers 。ここで( num => num % 2 == 0 )です。OrderBy ( n => n );C#は主に命令型言語ですが、時間の経過とともに常に関数型機能を追加しています。[ 103 ] [ 104 ]例えば、
varと C# 9 のターゲット型付けされた new 式new()C#には統一型システムがあります。この統一型システムは共通型システム(CTS)と呼ばれます。[ 111 ]:パート2、第4章:型システム
統一型システムとは、整数などのプリミティブ型を含むすべての型が、そのクラスのサブクラスであることを意味します。例えば、すべての型はメソッドを継承します。System.ObjectToString()
CTSはデータ型を2つのカテゴリに分類します。[ 111 ]
値型のインスタンスには、参照的な同一性も参照的な比較セマンティクスもありません。値型の等価性および不等価性の比較では、対応する演算子がオーバーロードされていない限り、インスタンス内の実際のデータ値が比較されます。値型は から派生し、常にデフォルト値を持ち、常に作成およびコピーできます。値型に関するその他の制限としては、互いに派生できないこと(ただし、インターフェースを実装することは可能)、および明示的なデフォルト(引数なし)コンストラクタを持つことができないことが挙げられます。これは、既に暗黙的なコンストラクタがあり、含まれるすべてのデータを型依存のデフォルト値(0、null、または同様)に初期化するためです。値型の例としては、すべてのプリミティブ型があります。例えば、(符号付き 32 ビット整数)、(32 ビット IEEE 浮動小数点数)、(16 ビット Unicode コード単位)、(通貨金額の処理に役立つ固定小数点数)、(ナノ秒精度で特定の時点を識別する)などです。その他の例としては、(列挙型)や(ユーザー定義構造体)などがあります。System.ValueTypeintfloatchardecimalSystem.DateTimeenumstruct
対照的に、参照型には参照同一性の概念があります。つまり、参照型の各インスタンスは、たとえ両方のインスタンス内のデータが同じであっても、他のすべてのインスタンスとは本質的に異なります。これは、参照型のデフォルトの等価性および不等価性の比較に反映されており、対応する演算子がオーバーロードされていない限り( の場合など)、構造的な等価性ではなく参照的な等価性をテストします。参照型のインスタンスの作成、既存のインスタンスのコピー、既存の 2 つのインスタンスに対する値の比較など、一部の操作は常に実行できるとは限りません。ただし、特定の参照型は、公開コンストラクターを公開するか、対応するインターフェイス( や など)を実装することで、そのようなサービスを提供できます。参照型の例としては、(他のすべての C# クラスの究極の基底クラス)、(Unicode 文字の文字列)、および(すべての C# 配列の基底クラス)などがあります。System.StringICloneableIComparableobjectSystem.StringSystem.Array
どちらの型カテゴリも、ユーザー定義型で拡張可能です。
ボクシングとは、値型オブジェクトを対応する参照型の値に変換する操作です。[ 111 ] C# ではボクシングは暗黙的に行われます。
アンボックスとは、参照型(以前にボックス化されていた)の値を値型の値に変換する操作です。[ 111 ] C# でのアンボックスには明示的な型キャストが必要です。型 T のボックス化されたオブジェクトは、T(または null 許容型 T)にのみアンボックスできます。[ 112 ]
例:
int foo = 42 ; // 値型。object bar = foo ; // foo は bar にボックス化されます。int foo2 = ( int ) bar ; // 値型にアンボックス化されます。C# の仕様では、コンパイラが利用できることを想定している最小限の型とクラスライブラリが詳細に規定されています。実際には、C# は多くの場合、ECMA-335 Common Language Infrastructure (CLI) として標準化されているCommon Language Infrastructure (CLI)の実装と組み合わせて使用されます。
標準のCLI仕様に加えて、.NETフレームワークライブラリの上に構築され、追加機能を提供する商用およびコミュニティクラスライブラリが多数存在する。[ 113 ]
C# は、.NET ライブラリおよびフレームワークのリストに含まれる任意のライブラリを呼び出すことができます。
以下は、C# 9 で導入されたトップレベルステートメント機能を使用した、古典的な「 Hello World」の例の非常にシンプルな C# プログラムです。 [ 114 ]
Console.WriteLine ( "Hello, World! " ) ;C# 8以前の言語で記述されたコードの場合、プログラムのエントリポイントロジックは、型内のMainメソッドに記述する必要があります。
Systemを使用します。class Program { static void Main () { Console . WriteLine ( "Hello, World!" ); } }このコードは、コンソールウィンドウに次のテキストを表示します。
こんにちは世界!
各行にはそれぞれ目的があります。
Systemを使用します。上記の行は、System名前空間内のすべての型をインポートします。たとえば、Consoleソースコードで後ほど使用されるクラスはSystem名前空間内で定義されているため、型の完全な名前(名前空間を含む)を指定せずに使用できます。
// 古典的な「Hello World」プログラムのバージョンこの行はコメントです。プログラマー向けにコードの説明とドキュメント化を行うものです。
クラスプログラム 上記はクラスの定義ですProgram。中括弧で囲まれた部分はすべて、そのクラスの定義を表しています。
{ ... }波括弧はコードブロックの境界を示します。この最初の例では、波括弧はProgramクラスの開始と終了を示しています。
static void Main ()これは、プログラムの実行が開始されるクラスメンバメソッドを宣言します。.NET ランタイムは、このMainメソッドを呼び出します。Java とは異なり、このMainメソッドにはキーワードは必要ありませんpublic。このキーワードは、メソッドがどのクラスからでもどこからでも呼び出せることをコンパイラに伝えます。[ 115 ]と書くことは、と書くことと同じです。staticキーワードにより、のインスタンスがなくてもメソッドにアクセスできます。各コンソールアプリケーションのエントリポイントは宣言する必要があります。そうしないと、プログラムはのインスタンスを必要としますが、どのインスタンスもプログラムを必要とします。この解決不可能な循環依存を回避するために、コンソールアプリケーション(上記のようなもの)を処理する C# コンパイラは、メソッドがない場合にエラーを報告します。キーワードは、が戻り値を持たないことを宣言します。(ただし、前述のように、C# 9 で導入されたトップレベルステートメントを使用して短いプログラムを記述できることに注意してください。)staticvoidMain(string[]args)privatestaticvoidMain(string[]args)ProgramMainstaticProgramstaticMainvoidMain
Console.WriteLine ( "Hello, World! " ) ;この行は出力を書き込みます。は名前空間Console内の静的クラスですSystem。コンソールアプリケーション用の標準入出力およびエラー ストリームへのインターフェースを提供します。プログラムは メソッド を呼び出しConsole、WriteLine引数である文字列 を含む行をコンソールに表示します"Hello, World!"。
.NET 2.0とC# 2.0では、.NET 1.xよりも柔軟なコレクションが利用できるようになりました。ジェネリクスがなかったため、開発者はArrayListなどのコレクションを使用して要素を型指定のないオブジェクトとして格納する必要がありましたが、その場合、格納されたアイテムのボックス化/アンボックス化/型チェック時にパフォーマンス上のオーバーヘッドが発生していました。
ジェネリクスは、開発者が型安全なデータ構造を作成できるという、.NET における画期的な新機能です。この変化は、レガシー システムの変換において特に重要であり、ジェネリクスへの更新によって、古いデータ構造をより効率的で型安全な代替手段に置き換えることで、パフォーマンスと保守性を大幅に向上させることができます。[ 116 ]
例
public class DataStore < T > { private T [] items = new T [ 10 ]; private int count = 0 ;public void Add ( T item ) { items [ count ++ ] = item ; }public T Get ( int index ) { return items [ index ]; } }2001 年 8 月、Microsoft、Hewlett-Packard、Intel は、C# および共通言語インフラストラクチャ(CLI) の仕様を標準化団体Ecma Internationalに提出することを共同で後援しました。2001 年 12 月、ECMA は ECMA-334 C# 言語仕様をリリースしました。C# は2003 年にISO / IEC標準になりました (ISO/IEC 23270:2003 -情報技術 - プログラミング言語 - C# )。ECMA は、2002 年 12 月に、C# の第 2 版として同等の仕様を採用していました。2005 年 6 月、ECMA は C# 仕様の第 3 版を承認し、ECMA-334 を更新しました。追加機能には、部分クラス、匿名メソッド、null 許容型、ジェネリクス(C++テンプレートにやや似ている) が含まれます。 2005年7月、ECMAはISO/IEC JTC 1/SC 22に対し、同委員会のファストトラック方式を通じて、規格および関連する技術報告書を提出した。このプロセスは通常6~9ヶ月かかる。
C#言語の定義とCLIは、ISO/IECおよびEcma規格に基づいて標準化されており、特許請求から合理的かつ非差別的なライセンス保護を提供します。
マイクロソフトは当初、 Open Specification Promiseでカバーされているフレームワークの部分について、非営利プロジェクトで特許を侵害したオープンソース開発者を訴えないことに同意した。[ 117 ]マイクロソフトはまた、 Novell製品に関連する特許を Novell の有料顧客に対して行使しないことにも同意した。[ 118 ]ただし、C#、.NET、または Novell の .NET 実装 ( The Mono Project ) を明示的に言及していない製品のリストは例外である。[ 119 ]しかし、Novell は Mono がマイクロソフトの特許を侵害していないと主張した。[ 120 ]マイクロソフトはまた、 Novell を通じて入手した場合、Mono に依存するMoonlight ブラウザ プラグインに関連する特許権を行使しないという特定の合意も行った。 [ 121 ]
それから10年後、マイクロソフトはC#向けの無料かつオープンソースのクロスプラットフォームツール、すなわちVisual Studio Code、.NET Core、およびRoslynの開発を開始した。Monoは、マイクロソフトの子会社であるXamarinのプロジェクトとしてマイクロソフトに加わった。
Microsoft は、オープンソースのリファレンス C# コンパイラとツールを開発しました。最初のコンパイラであるRoslyn は中間言語 (IL) にコンパイルし、2 番目の RyuJIT [ 122 ]は JIT (just-in-time) コンパイラで、動的でオンザフライの最適化を行い、IL を CPU のフロントエンド用のネイティブ コードにコンパイルします。[ 123 ] RyuJIT はオープンソースで、C++ で記述されています。[ 124 ] Roslyn は完全にマネージド コード(C#) で記述されており、公開され、機能が API として公開されています。これにより、開発者はリファクタリング ツールや診断ツールを作成できます。[ 5 ] [ 125 ]公式実装の 2 つのブランチは、.NET Framework (クローズド ソース、Windows のみ) と .NET Core (オープンソース、クロス プラットフォーム) であり、最終的に 1 つのオープンソース実装である .NET 5.0 に統合されました。[ 126 ] .NET Framework 4.6 では、新しい JIT コンパイラが以前のものに取って代わりました。[ 122 ] [ 127 ]
その他のC#コンパイラ(共通言語インフラストラクチャと.NETクラスライブラリの実装を含むものもある):
Unityゲームエンジンは、主要なスクリプト言語としてC#を使用しています。Godotゲームエンジンは、 Microsoftからの24,000ドルの寄付により、オプションのC#モジュールを実装しました。[ 128 ]
C# は Java から強い影響を受けていますが、C++ からも強い影響を受けており、C++ と Java の両方の子孫と見なすのが最適です。
私たちは皆、巨人の肩の上に立っており、すべての言語はそれ以前のものの上に構築されているため、C、C++、Java、Delphi、そして私たちより前に存在したこれらすべてのものに多大な恩義があります。(
アンダース・ヘイルスバーグ
)
や、C#、Go、Pythonなどの他の言語から大きな影響を受けています。
私の意見では、Java言語にこのような根本的な変化をもたらしたのはC#です。(
バリー・コーネリアス
)
言語は、言語のエキスパート、ドキュメントの達人、コンパイラ最適化の達人、そしてアイデアの洗練と実戦テストに役立つフィードバックを提供した非常に重要な社内ドッグフーディング グループのたゆまぬ努力の産物です。もちろん、Objective-C、Rust、Haskell、Ruby、Python、C#、CLU など、挙げきれないほど多くの言語からアイデアを取り入れ、この分野の他の多くの言語が苦労して得た経験からも大いに恩恵を受けています。
{{cite web}}: CS1 maint: 数値名: 著者リスト (リンク)マイクロソフトは、自社およびその子会社(総称して「マイクロソフト」)を代表して、ノベルまたはその子会社(総称して「ノベル」)が配布した対象製品の特定のコピーをノベルが(直接または間接的に)収益として受け取った顧客が、マイクロソフトの対象特許を侵害したとして、ノベルの顧客およびノベルの子会社の顧客を訴えないことをここに誓約する。ただし、上記の誓約は、当該顧客による(i)ノベルが当該収益の対価として許可した特定のコピーの使用、および(ii)ノベルが当該収益の対価として許可した範囲内での使用に限定される。
当社は、Monoがマイクロソフトの特許を侵害していないと主張します。
「下流の受領者」とは、Novell から直接、または中間受領者を通じて入手した Moonlight 実装をその意図された目的に使用するエンティティまたは個人を意味します。Microsoft は、上記の契約を更新 (中止を含む) する権利を留保します。「Moonlight 実装」とは、パーソナル コンピュータ上のブラウザーのプラグインとしてのみ実行され、GPLv3 または同様のライセンスの下でライセンスされていない Moonlight 1.0 または Moonlight 1.1 の特定の部分のみを意味します。