C Sharp
C#
パラダイム | 構造化, 命令型, オブジェクト指向, 関数型, イベント駆動型, ジェネリック, リフレクション, 並行計算 |
---|---|
登場時期 | 2000年 |
設計者 | マイクロソフト(アンダース・ヘルスバーグ率いるチーム) |
開発者 | マイクロソフト |
最新リリース | 5.0 / 2012年8月15日 |
型付け | 強い静的型付け(4.0から動的型導入) |
主な処理系 | 共通言語ランタイム, Mono, DotGNU |
方言 | 1.0, 1.5, 2.0 (ECMA), 3.0, 3.5, 4.0, 5.0 |
影響を受けた言語 | C++, Delphi, Eiffel, Java,LISP |
影響を与えた言語 | D言語, F#, Java,Nemerle, Vala |
プラットフォーム | Microsoft Windows他 |
C#(シーシャープ)とは、マイクロソフトが開発したマルチパラダイムプログラミング言語。強い型付け、命令型、宣言型、手続き型、関数型、ジェネリック、オブジェクト指向の要素を持つ。
マイクロソフトのソフトウェアフレームワークである.NET Frameworkとともに作られ、Ecma International[1]および国際標準化機構 (ISO)[2] によって標準化されており、日本においても日本工業規格 (JIS)[3]によって採択された。
概要
開発にはボーランド社のTurbo PascalやDelphiを開発したアンダース・ヘルスバーグを筆頭に多数のDelphi開発陣が参加している。
C#は共通言語基盤(共通言語ランタイムなど)が解釈する共通中間言語にコンパイルされて実行される。基本的な書式がC言語風になっているため、初見の構文はサン・マイクロシステムズ社によるJavaに近いと言われるが、実際の構文はDelphiに準じており、C言語風ということもありC++ Builderの独自拡張構文に極めて近い内容となっている。またプロパティやデリゲートなどDelphiの構文そのまま、もしくは名称変更しただけの機能となっているものが多い。
自動ボックス化、デリゲート、プロパティ、インデクサ、カスタム属性、ポインタ演算操作、構造体(値型オブジェクト)、多次元配列、可変長引数、などの機能を持つ。また、Javaと同様に大規模ライブラリ、プロセッサ・アーキテクチャに依存しない実行形態、ガベージコレクション、JITコンパイルによる実行の高速化、などが実現されている(もっともこれらはC#の機能というより.NET Frameworkによるものである)。
.NET構想における中心的な開発言語であり、XML WebサービスやASP.NETの記述にも使用される。他の.NET系の言語でも記述可能だが、生産性・機能においてC#が最も優れるとされる。マイクロソフトの統合開発環境では、Microsoft Visual C#がC#に対応している。
共通言語仕様のCLSによって、他のCLS準拠の言語(Visual Basic .NETやVisual C++ (C++/CLI)など)と相互に連携することができる。他言語で記述されたクラスを継承することも、またその逆も可能である。
言語仕様[編集]
さまざまな意味において、基盤であるCLIの機能をもっとも反映している言語であるといえる。C#にある組み込み型のほとんどは、CLIフレームワークに実装されている値型と対応している。しかし、C#の言語仕様はコンパイラのコード生成については何も言及していない。つまり、CLRに対応しなければならないとか、共通中間言語 (CIL) などの特定のフォーマットのコードを生成しなければならないとかいうことは述べられていない。そのため、理論的にはC++やFORTRANのように環境依存のマシン語を生成することも可能である。しかし、現在存在するすべてのC#コンパイラはCLIをターゲットにしている。
CやC++からの改良点
C#では、CやC++と比較してさまざまな制限や改良が加えられている。その例を次に挙げる。
- グローバル変数やグローバルメソッドは存在しない。すべてのメソッドとメンバはクラスの一部として宣言されなければならない。
- 外のブロックで宣言した変数名を、内のブロックで再宣言してはいけない。これはC++ではしばしば混乱や曖昧のもととされているが、C#では禁止されている。
- Cの
printf()
関数のように関数をグローバルで公開するのではなく、すべての関数はクラス内で宣言されなければならない。ほとんどの場合クラスは名前の衝突を避けるために名前空間に所属する。 - 名前空間は階層構造をもつ。つまり、名前空間は他の名前空間の中に宣言することができる。
- 原始型を含めたすべての型は、
object
クラスの派生クラスである。つまりobject
クラスのもつすべてのプロパティやメソッドを継承する。例えば、すべての型はToString()
メソッドをもつ。 - C#にはブール型
bool
が存在する。while
やif
のように条件をとるステートメントには、bool
型の式を与えなければならない。CやC++にもブール型が存在するが、これは整数型と相互に変換可能で、while
文やif
文に与える式として整数やポインタも許容していた。C#ではミスを防止するために、このブール型と整数が可換であるという仕様を禁止している。 - ポインタをサポートする。ポインタは
unsafe
スコープ内のみで使用することができ、適切な権限をもつプログラムのみがunsafe
とマークされたコードを実行することができる。オブジェクトへのアクセスの大部分は管理された安全な参照によってなされ、大部分の算術演算はオーバフローのチェックがなされる。unsafe
ポインタは値型や文字列を指すことができる。セーフコードでは、必ずしもそうする必要はないものの、IntPtr
型を通してポインタをやりとりすることができる。 - マネージドなメモリを明示的に解放する方法は存在せず、参照されなくなったメモリはガベージコレクタによって自動的に解放される。ガベージコレクタは、メモリの解放忘れによって起こるメモリリークを解消する。C#は、データベース接続のようなアンマネージドなリソースに対しても明示的に制御する方法を提供している。これは
IDisposable
インタフェースとusing
ステートメントによってなされる。 - クラスは複数のインタフェースを実装することができるが、多重継承はサポートされない。
- C#はC++に比べて型安全である。既定の暗黙変換は、整数の範囲を広げる変換や、派生クラスから基底クラスへの変換といった、安全な変換のみに限定される。これは、コンパイル時、JITコンパイル時、そして一部の動的なケースでは実行時に強制される。ブール型と整数型、列挙型と整数型、の間は暗黙変換はできない。暗黙変換をユーザ定義する際は、明示的にそのように指定しなければならない。これはC++のコンストラクタとは違った仕様である。
- 列挙型のメンバは、列挙型の名前空間の中におかれる。また、列挙型の定数名を取得することができる。さらに、列挙型の定数名から動的に定数値を得ることができる。
- プロパティと呼ばれるアクセサは、C++におけるメンバフィールドのような構文でオブジェクトにアクセスすることができる。C++では、
public
としてメンバを宣言することでメンバを読むことも変更することもできるようになるが、C#ではプロパティによってメンバアクセスやデータの正当性チェックを制御することができる。 - switch文で、基本型のみならず、定数文字列によって分岐することができる。