共通言語仕様
更新 : 2007 年 11 月
オブジェクトがどの言語で実装されている場合でも、複数のオブジェクト間で完全な対話ができるようにするためには、相互運用のために使用するすべての言語の共通機能だけを呼び出し側に公開するように、オブジェクトを実装しなければなりません。そのために、多くのアプリケーションで必要とされる基本的な言語機能のセットである共通言語仕様 (CLS: Common Language Specification) が定義されています。共通型システム (CLS: Common Type System) の規則は、共通型システムのサブセットを定義しています。つまり、CLS に適用されるすべての規則が共通型システムにも適用されます。ただし、CLS ではより厳密な規則が定義されています。CLS により、開発者が信頼できる一連の機能が幅広い言語で利用できるように定義され、言語の相互運用性が強化されます。また、CLS では CLS に準拠するための要件も規定されており、これにより、記述したマネージ コードが CLS に準拠しているかどうか、または CLS 機能を使用するマネージ コードの開発が特定のツールでどの程度サポートされているかを判断できます。
記述したコンポーネントが、派生クラスなどのほかのコードに公開する API で CLS 機能だけを使用する場合、そのコンポーネントには CLS をサポートするすべてのプログラミング言語から確実にアクセスできます。CLS の規則を遵守し、CLS に規定されている機能だけを使用するコンポーネントは、CLS 準拠コンポーネントと呼ばれます。
.NET Framework クラス ライブラリの概要の型で定義されたメンバのほとんどは CLS 準拠です。しかし、このクラス ライブラリ内には、CLS 準拠ではないメンバを含む型もいくつかあります。これらのメンバは、CLS には規定されていない言語機能をサポートするために使用されます。CLS に準拠しない型とメンバは、リファレンス ドキュメントに記載されています。これらの型とメンバの代わりとなる CLS に準拠した型とメンバが用意されています。.NET Framework クラス ライブラリの型の詳細については、「.NET Framework クラス ライブラリ リファレンス」を参照してください。
CLS は、開発者が共通して必要とする言語構成要素を網羅するために十分なサイズを確保し、同時に多くの言語でサポートできるくらい小さくデザインされています。また、コードがタイプ セーフかどうかを迅速に検証できない言語構成要素は CLS から除外され、必要に応じて CLS 準拠のすべての言語で検証可能なコードを作成できるようになっています。タイプ セーフ コードの検証の詳細については、「MSIL からネイティブ コードへのコンパイル」を参照してください。
CLS で規定されている機能をまとめた表を次に示します。これらの機能が、開発者とコンパイラの両方 (すべて) に適用されるのか、コンパイラだけ適用されるのかも示されています。この表は参照用であり、すべてを詳細に網羅したものではありません。詳細については、Microsoft Developer Network の Web サイトにある「Common Language Infrastructure」の仕様「Partition I - Architecture」を参照してください。
機能 |
対象 |
説明 |
---|---|---|
一般 |
|
|
[可視性] |
すべて |
CLS 規則は、型のうち、定義しているアセンブリの外部に公開される部分にだけ適用されます。 |
グローバル メンバ |
すべて |
グローバルで静的な (static) フィールドとメソッドは CLS 準拠ではありません。 |
名前付け |
|
|
文字および大文字と小文字の区別 |
すべて |
CLS 準拠の言語コンパイラは、Unicode Standard 3.0 の Technical Report 15 の Annex 7 の規則に準拠する必要があります。この規則は、識別子の先頭および中に含めることができる文字を規定しています。この規則は、Unicode Consortium の Web サイトから入手できます。 2 つの識別子の区別には、大文字と小文字の相違は使用できません。 |
キーワード |
コンパイラ |
CLS 準拠の言語コンパイラは、キーワードと一致してしまう識別子を参照できるようにする機構を提供する必要があります。また、CLS 準拠の言語コンパイラは、その言語のキーワードが名前になっている仮想メソッドを定義またはオーバーライドするための機構も提供する必要があります。 |
一意性 |
すべて |
CLS 準拠のスコープ内では、すべての名前を区別する必要があります。2 つのメンバの種類が異なる場合でも、それらの名前を区別する必要がありますが、名前が同一でもオーバーロードによって解決される場合は除きます。たとえば、CLS では、1 つの型でメソッドとフィールドに対して同じ名前は使用できません。 |
シグネチャ |
すべて |
型やメンバのシグネチャに含まれる戻り値の型およびパラメータの型はすべて CLS 準拠であることが必要です。 |
型 |
|
|
プリミティブ型 |
すべて |
.NET Framework クラス ライブラリには、コンパイラが使用するプリミティブ データ型に対応する型が含まれています。これらの型のうち、Byte、Int16、Int32、Int64、Single、Double、Boolean、Char、Decimal、IntPtr、および String が CLS 準拠です。これらの型の詳細については、「.NET Framework クラス ライブラリの概要」の型の表を参照してください。 |
ボックス化された型 |
すべて |
ボックス化された値型 (オブジェクトに変換された値型) は CLS 準拠ではありません。代わりに、必要に応じて System.Object、System.ValueType、または System.Enum を使用してください。 |
[可視性] |
すべて |
型宣言およびメンバ宣言には、宣言される型またはメンバよりも参照可能範囲またはアクセシビリティが低い型を含めることはできません。 |
インターフェイス メソッド |
コンパイラ |
CLS 準拠の言語コンパイラには、1 つの型が 2 つのインターフェイスを実装していて、これらのインターフェイスのそれぞれが同じ名前とシグネチャを持つメソッドの定義を必要としている状況を処理できる構文が必要です。これらのメソッドは、互いに異なるものと解釈される必要があり、同じ実装を持つ必要はありません。 |
閉鎖性 |
すべて |
CLS 準拠のインターフェイスおよび抽象クラスの個々のメンバは、CLS に準拠するように定義する必要があります。 |
コンストラクタの呼び出し |
すべて |
コンストラクタは、継承されたインスタンス データにアクセスする前に、基本クラスのコンストラクタを呼び出す必要があります。 |
型指定された参照 |
すべて |
型指定された参照は CLS 準拠ではありません。型指定された参照は、オブジェクトへの参照および型への参照を含む特別な構造です。型指定された参照を使用すると、共通言語ランタイムでは、引数の数が異なるメソッドを C++ と同じような方法でサポートできるようになります。 |
型のメンバ |
|
|
オーバーロード |
すべて |
インデックス付きのプロパティ、メソッド、コンストラクタはオーバーロードできます。フィールドとイベントはオーバーロードしません。 プロパティについては、型 (プロパティの getter メソッドの戻り値の型) によるオーバーロードはできませんが、インデックスの数や型が異なる場合のオーバーロードは可能です。 メソッドは、パラメータの数と型に基づいてのみ、またジェネリック メソッドの場合はジェネリック パラメータの数に基づいてのみ、オーバーロードされます。 演算子のオーバーロードは CLS 準拠にはなりません。ただし、CLS には、Add() などの有用な名前を付け、メタデータのビットを設定する方法についてのガイドラインが用意されています。演算子のオーバーロードをサポートするコンパイラはこのガイドラインに準拠することが推奨されますが、必須ではありません。 |
オーバーロードされたメンバの一意性 |
すべて |
フィールドおよび入れ子にされた型は、識別子を比較するだけで区別できることが必要です。識別子を比較した結果、名前が同じメソッド、プロパティ、イベントは、戻り値の型以外で区別できるようにする必要があります。 |
変換演算子 |
すべて |
op_Implicit または op_Explicit のいずれかがその戻り値の型でオーバーロードされた場合は、その代わりとなる変換方法を提供する必要があります。 |
メソッド |
|
|
オーバーライドされたメソッドのアクセシビリティ |
すべて |
継承されたメソッドをオーバーライドする場合にアクセシビリティは変更できません。ただし、別のアセンブリから継承されたメソッドを FamilyOrAssembly アクセシビリティでオーバーライドする場合は除きます。この場合は、オーバーライドに Family アクセシビリティが必要です。 |
引数リスト |
すべて |
CLS でサポートされる呼び出し規約は、標準のマネージ呼び出し規約だけです。可変長の引数リストは使用できません。可変個の引数をサポートするには、Microsoft Visual Basic では ParamArray キーワード、C# では params キーワードを使用してください。 |
プロパティ |
|
|
アクセサのメタデータ |
コンパイラ |
プロパティのメソッドを実装する getter メソッドと setter メソッドは、メタデータ中で mdSpecialName 識別子でマークする必要があります。 |
修飾子 |
すべて |
プロパティとそのアクセサは、すべてが static、すべてが virtual、またはすべてが instance のいずれかにする必要があります。 |
アクセサ名 |
すべて |
プロパティは、特定の名前付け規則に従う必要があります。たとえば Name というプロパティでは、getter メソッドを定義する場合、その名前は get_Name に、setter メソッドを定義する場合、その名前は set_Name にします。 |
戻り値の型と引数の型 |
すべて |
プロパティの型は、getter メソッドの戻り値の型と、setter メソッドの最後の引数の型です。プロパティのパラメータの型は、getter メソッドのパラメータの型と、setter メソッドの final パラメータを除くすべてのパラメータの型です。これらすべての型は CLS 準拠であることが必要です。また、マネージ ポインタにしたり、参照渡ししたりすることはできません。 |
イベント |
|
|
イベント メソッド |
すべて |
イベントを追加および削除するメソッドは、両方とも提供するか、両方とも提供しないかのいずれかにする必要があります。 |
イベント メソッドのメタデータ |
コンパイラ |
イベントを実装するメソッドは、メタデータ中で mdSpecialName 識別子でマークする必要があります。 |
アクセサのアクセシビリティ |
すべて |
イベントの追加、削除、発生メソッドのアクセシビリティは同一にする必要があります。 |
修飾子 |
すべて |
イベントの追加、削除、発生メソッドは、すべてが static、すべてが virtual、またはすべてが instance のいずれかにする必要があります。 |
イベント メソッド名 |
すべて |
イベントは、特定の名前付け規則に従う必要があります。たとえば MyEvent というイベントでは、追加メソッドを定義する場合、その名前は add_MyEvent に、削除メソッドを定義する場合、その名前は remove_MyEvent に、発生メソッドを定義する場合、その名前は raise_MyEvent にします。 |
引数 |
すべて |
イベントを追加および削除する各メソッドは、イベントの型を定義する型のパラメータを 1 つ受け入れる必要があります。この型は、System.Delegate から派生する必要があります。 |
ポインタ型 |
|
|
ポインタ |
すべて |
ポインタ型および関数ポインタ型は CLS 準拠ではありません。 |
インターフェイス |
|
|
メンバ シグネチャ |
すべて |
CLS 準拠のインターフェイスは、CLS に準拠しないメソッドを実装するために、これらのメソッドの定義を要求することはできません。 |
メンバ修飾子 |
すべて |
CLS 準拠のインターフェイスは、静的メソッドを定義することも、フィールドを定義することもできません。これらのインターフェイスでは、プロパティ、イベント、仮想メソッドを定義できます。 |
参照型 |
|
|
コンストラクタの呼び出し |
すべて |
参照型については、オブジェクト コンストラクタはオブジェクト作成時に呼び出されるだけで、オブジェクトは一度しか初期化されません。 |
クラス型 |
|
|
継承 |
すべて |
CLS 準拠クラスは、CLS 準拠クラスを継承する必要があります (System.Object は CLS 準拠です)。 |
配列1 |
|
|
要素型 |
すべて |
配列の要素は、CLS 準拠の型であることが必要です。 |
次元 |
すべて |
配列の次元数は、0 より大きい固定数であることが必要です。 |
境界 |
すべて |
配列の次元の下限値は 0 にする必要があります。 |
列挙体 |
|
|
基になる型 |
すべて |
列挙体の基になる型は、組み込みの CLS 整数型 (Byte、Int16、Int32、または Int64) であることが必要です。 |
FlagsAttribute |
コンパイラ |
列挙体の定義に System.FlagsAttribute カスタム属性が含まれている場合は、この列挙体を一連のビットフィールド (フラグ) として扱う必要があることを意味します。この属性が含まれていない場合は、この型を列挙定数のグループとして扱う必要があることを意味します。これら 2 種類の列挙体を区別するには、各言語で FlagsAttribute または言語固有の構文を使用することをお勧めします。 |
フィールド メンバ |
すべて |
列挙体のリテラルの静的 (static) フィールドは、列挙体自体の型と同じ型であることが必要です。 |
例外 |
|
|
継承 |
すべて |
スローされるオブジェクトは、System.Exception 型であるか、または System.Exception から継承する必要があります。 |
カスタム属性 |
|
|
値のエンコーディング |
コンパイラ |
CLS 準拠のコンパイラは、カスタム属性のエンコーディングのサブセット (メタデータでのカスタム属性の表現) だけを扱う必要があります。これらのエンコーディングに使用できる型は、System.Type、System.String、System.Char、System.Boolean、System.Byte、System.Int16、System.Int32、System.Int64、System.Single、System.Double、および CLS 準拠ベースの整数型に基づく列挙型だけです。 |
メタデータ |
|
|
CLS 準拠 |
すべて |
型とそれらを定義するアセンブリとで、CLS 準拠の方法が異なる場合、それらの型を System.CLSCompliantAttribute でマークする必要があります。同様に、メンバとそれらの型とで CLS 準拠の方法が異なる場合には、それらのメンバもマークする必要があります。メンバまたは型に非 CLS 準拠のマークを付けた場合は、CLS に準拠した代替のメンバまたは型を提供する必要があります。 |
ジェネリック |
||
型名 |
コンパイラ |
ジェネリック型の名前は、その型で宣言された型パラメータの数をエンコードする必要があります。入れ子になったジェネリック型の名前は、その型に対して新たに導入された型パラメータの数をエンコードする必要があります。 |
入れ子にされた型 |
コンパイラ |
入れ子にされた型は、少なくともそれを囲む型と同じ数のジェネリック パラメータを含む必要があります。入れ子にされた型のジェネリック パラメータは、それを囲む型のジェネリック パラメータと、位置によって対応します。 |
制約 |
すべて |
ジェネリック型は、基本型またはインターフェイスに対する制約を満たすことが保証される制約を宣言する必要があります。 |
制約型 |
すべて |
ジェネリック パラメータで制約として使用される型は、それ自体が CLS 準拠であることが必要です。 |
メンバ シグネチャ |
すべて |
インスタンス化されたジェネリック型のメンバ (入れ子にされた型を含む) の参照範囲とアクセシビリティは、ジェネリック型の宣言全体ではなく固有のインスタンス化を対象としていると見なされます。 |
ジェネリック メソッド |
すべて |
抽象または仮想の各ジェネリック メソッドには、それぞれ既定の具象 (非抽象) 実装が必要です。 |
1. ジャグ配列、つまり配列の配列は、CLS 準拠です。.NET Framework Version 1.0 では、C# コンパイラが誤ってそれらが CLS 準拠ではないと報告します。