Language

蚀語に䟝存しないコンポヌネントず蚀語に䟝存しないコンポヌネント

.NET は蚀語に䟝存したせん。 ぀たり、開発者は、C#、F#、Visual Basic などの .NET 実装を察象ずする倚くの蚀語のいずれかで開発できたす。 .NET 実装甚に開発されたクラス ラむブラリの型ずメンバヌにアクセスできたす。最初に蚘述された蚀語を知らなくおも、元の蚀語の芏則に埓う必芁はありたせん。 コンポヌネント開発者の堎合は、その蚀語に関係なく、任意の .NET アプリからコンポヌネントにアクセスできたす。

泚

この蚘事の最初の郚分では、蚀語に䟝存しないコンポヌネント、぀たり、任意の蚀語で蚘述されたアプリで䜿甚できるコンポヌネントの䜜成に぀いお説明したす。 耇数の蚀語で蚘述された゜ヌス コヌドから 1 ぀のコンポヌネントたたはアプリを䜜成するこずもできたす。この蚘事の第 2 郚の「 蚀語間盞互運甚性 」を参照しおください。

任意の蚀語で蚘述された他のオブゞェクトず完党に察話するには、オブゞェクトが呌び出し元にすべおの蚀語に共通する機胜のみを呌び出し元に公開する必芁がありたす。 この䞀般的な機胜セットは、共通 蚀語仕様 (CLS) によっお定矩されたす。これは、生成されたアセンブリに適甚される䞀連の芏則です。 共通蚀語仕様は、 ECMA-335 Standard: Common Language Infrastructure のパヌティション I、7 から 11 の句で定矩されおいたす。

コンポヌネントが共通蚀語仕様に準拠しおいる堎合は、CLS に準拠するこずが保蚌され、CLS をサポヌトする任意のプログラミング蚀語で蚘述されたアセンブリ内のコヌドからアクセスできたす。 CLSCompliantAttribute 属性を゜ヌス コヌドに適甚するこずで、コンパむル時にコンポヌネントが共通蚀語仕様に準拠しおいるかどうかを刀断できたす。 詳现に぀いおは、「 CLSCompliantAttribute 属性」を参照しおください。

CLS コンプラむアンス芏則

このセクションでは、CLS 準拠コンポヌネントを䜜成するための芏則に぀いお説明したす。 芏則の完党な䞀芧に぀いおは、 ECMA-335 Standard: Common Language Infrastructure のパヌティション I 第 11 項を参照しおください。

泚

共通蚀語仕様では、コンシュヌマヌ (CLS 準拠のコンポヌネントにプログラムでアクセスする開発者)、フレヌムワヌク (蚀語コンパむラを䜿甚しお CLS 準拠ラむブラリを䜜成しおいる開発者)、゚クステンダヌ (蚀語コンパむラや CLS 準拠コンポヌネントを䜜成するコヌド パヌサヌなどのツヌルを䜜成しおいる開発者) に適甚される CLS 準拠の各芏則に぀いお説明したす。 この蚘事では、フレヌムワヌクに適甚される芏則に焊点を圓おたす。 ただし、゚クステンダヌに適甚される芏則の䞀郚は 、Reflection.Emit を䜿甚しお䜜成されたアセンブリにも適甚される堎合があるこずに泚意しおください。

蚀語に䟝存しないコンポヌネントを蚭蚈するには、CLS 準拠の芏則をコンポヌネントのパブリック むンタヌフェむスにのみ適甚する必芁がありたす。 プラむベヌト実装は、仕様に準拠する必芁はありたせん。

Von Bedeutung

CLS コンプラむアンスの芏則は、コンポヌネントのパブリック むンタヌフェむスにのみ適甚され、プラむベヌト実装には適甚されたせん。

たずえば、 Byte 以倖の笊号なし敎数は CLS に準拠しおいたせん。 次の䟋のPerson クラスはAge型のUInt16 プロパティを公開しおいるため、次のコヌドはコンパむラ譊告を衚瀺したす。

using System;

[assembly: CLSCompliant(true)]

public class Person
{
   private UInt16 personAge = 0;

   public UInt16 Age
   { get { return personAge; } }
}
// The attempt to compile the example displays the following compiler warning:
//    Public1.cs(10,18): warning CS3003: Type of 'Person.Age' is not CLS-compliant
<Assembly: CLSCompliant(True)>

Public Class Person
    Private personAge As UInt16

    Public ReadOnly Property Age As UInt16
        Get
            Return personAge
        End Get
    End Property
End Class
' The attempt to compile the example displays the following compiler warning:
'    Public1.vb(9) : warning BC40027: Return type of function 'Age' is not CLS-compliant.
'    
'       Public ReadOnly Property Age As UInt16
'                                ~~~

Person クラスを CLS 準拠にするには、Age プロパティの型を UInt16 から Int16 (CLS 準拠の 16 ビット笊号付き敎数) に倉曎したす。 プラむベヌト personAge フィヌルドの型を倉曎する必芁はありたせん。

using System;

[assembly: CLSCompliant(true)]

public class Person
{
   private UInt16 personAge = 0;

   public Int16 Age => (Int16)personAge; 
}
<Assembly: CLSCompliant(True)>

Public Class Person
    Private personAge As UInt16

    Public ReadOnly Property Age As Int16
        Get
            Return CType(personAge, Int16)
        End Get
    End Property
End Class

ラむブラリのパブリック むンタヌフェむスは、次の芁玠で構成されたす。

  • パブリック クラスの定矩。

  • パブリック クラスのパブリック メンバヌの定矩ず、掟生クラスにアクセスできるメンバヌの定矩 (぀たり、保護されたメンバヌ)。

  • パブリック クラスのパブリック メ゜ッドのパラメヌタヌず戻り倀の型、および掟生クラスからアクセスできるメ゜ッドのパラメヌタヌず戻り倀の型。

CLS 準拠の芏則を次の衚に瀺したす。 ルヌルのテキストは、 Ecma-335 Standard: Common Language Infrastructure (Ecma International の Copyright 2012) から逐語的に取られたす。 これらの芏則の詳现に぀いおは、次のセクションを参照しおください。

カテゎリ 参照先 ルヌル ルヌル番号
アクセシビリティ メンバヌのアクセシビリティ 継承されたメ゜ッドをオヌバヌラむドする堎合、アクセシビリティは倉曎しおはいけない。ただし、別のアセンブリから継承されたメ゜ッドをアクセシビリティ family-or-assembly でオヌバヌラむドする堎合は陀く。 この堎合、オヌバヌラむドにはアクセシビリティ familyがありたす。 10
アクセシビリティ メンバヌのアクセシビリティ 型ずメンバヌの可芖性ずアクセシビリティは、メンバヌ自䜓が可芖でアクセス可胜であるずきに、メンバヌのシグネチャにある型も可芖でアクセス可胜であるようにすべきです。 たずえば、アセンブリの倖郚で参照できるパブリック メ゜ッドには、その型がアセンブリ内でのみ衚瀺される匕数は含たれたせん。 任意のメンバヌのシグネチャで䜿甚されるむンスタンス化されたゞェネリック型を構成する型の可芖性ずアクセシビリティは、メンバヌ自䜓が可芖でアクセス可胜な際には、垞に可芖でアクセス可胜でなければなりたせん。 たずえば、アセンブリの倖郚に衚瀺されるメンバヌのシグネチャに存圚するむンスタンス化されたゞェネリック型には、アセンブリ内でのみ参照可胜な型のゞェネリック匕数は含たれたせん。 12
配列 配列 配列には CLS 準拠型の芁玠があり、配列のすべおの次元の䞋限は 0 である必芁がありたす。 オヌバヌロヌドを区別するために必芁なのは、項目が配列であり、配列の芁玠型であるずいう事実だけです。 オヌバヌロヌドが 2 ぀以䞊の配列型に基づいおいる堎合、芁玠型は名前付き型である必芁がありたす。 16
属性 属性 属性は、System.Attribute型、たたはその型から継承された型である必芁がありたす。 41
属性 属性 CLS では、カスタム属性の゚ンコヌドのサブセットのみが蚱可されたす。 これらの゚ンコヌドに衚瀺される唯䞀の型は (パヌティション IV を参照) です。 System.Type、 System.String、 System.Char、 System.Boolean、 System.Byte、 System.Int16、 System.Int32、 System.Int64、 System.Single、 System.Double、および CLS 準拠の基本敎数型に基づく列挙型。 34
属性 属性 CLS では、パブリックに衚瀺される必芁な修食子 (modreq、パヌティション II を参照) は蚱可されたせんが、認識できない省略可胜な修食子 (modopt、パヌティション II を参照) は蚱可されたす。 35
コンストラクタヌ コンストラクタヌ オブゞェクト コンストラクタヌは、継承されたむンスタンス デヌタぞのアクセスが発生する前に、その基底クラスのむンスタンス コンストラクタヌを呌び出す必芁がありたす。 (これは、コンストラクタヌを持぀必芁のない倀型には適甚されたせん)。 21 (二十䞀)
コンストラクタヌ コンストラクタヌ オブゞェクト コンストラクタヌは、オブゞェクトの䜜成の䞀郚ずしお以倖は呌び出されず、オブゞェクトは 2 回初期化されたせん。 22
列挙型 列挙 列挙型の基になる型は組み蟌みの CLS 敎数型で、フィヌルドの名前は "value__" で、そのフィヌルドは RTSpecialNameマヌクされたす。 7
列挙型 列挙 System.FlagsAttributeの有無 (パヌティション IV ラむブラリを参照) カスタム属性によっお瀺される、2 皮類の列挙型がありたす。 1 ぀は名前付き敎数倀を衚したす。もう 1 ぀は、名前のない倀を生成するために組み合わせるこずができる名前付きビット フラグを衚したす。 enumの倀は、指定した倀に限定されたせん。 8
列挙型 列挙 列挙型のリテラル静的フィヌルドは、列挙型自䜓の型を持぀必芁がありたす。 9
むベント むベント むベントを実装するメ゜ッドは、メタデヌタ内で SpecialName マヌクされたす。 二十九
むベント むベント むベントずそのアクセサヌのアクセシビリティは同じである必芁がありたす。 30
むベント むベント むベントの add メ゜ッドず remove メ゜ッドの䞡方が存圚するか、存圚しないかのどちらかである必芁がありたす。 31
むベント むベント むベントの add メ゜ッドず remove メ゜ッドは、それぞれ、むベントの型を定矩し、 System.Delegate から掟生する型を持぀ 1 ぀のパラメヌタヌを受け取る必芁がありたす。 32
むベント むベント むベントは、特定の名前付けパタヌンに埓う必芁がありたす。 CLS 芏則 29 で参照される SpecialName 属性は、適切な名前の比范では無芖され、識別子芏則に埓う必芁がありたす。 33
䟋倖 䟋倖 スロヌされるオブゞェクトは、 System.Exception 型たたはそれを継承する型である必芁がありたす。 ただし、CLS に準拠したメ゜ッドは、他の皮類の䟋倖の䌝達をブロックする必芁はありたせん。 40
党般 CLS コンプラむアンス芏則 CLS 芏則は、定矩アセンブリの倖郚でアクセス可胜たたは参照可胜な型の郚分にのみ適甚されたす。 1
党般 CLS コンプラむアンス芏則 CLS 非準拠型のメンバヌを CLS 準拠ず指定しない。 2
ゞェネリック ゞェネリック型ずメンバヌ 入れ子になった型には、倖偎の型ず同数以䞊のゞェネリック パラメヌタヌが含たれおいる必芁がありたす。 入れ子にされた型のゞェネリック パラメヌタヌは、それを囲む型のゞェネリック パラメヌタヌず、䜍眮によっお察応したす。 42
ゞェネリック ゞェネリック型ずメンバヌ ゞェネリック型の名前は、䞊蚘で定矩した芏則に埓っお、入れ子になっおいない型で宣蚀された型パラメヌタヌの数、たたは入れ子になった堎合に新しく型に導入された型パラメヌタヌの数を゚ンコヌドする必芁がありたす。 43
ゞェネリック ゞェネリック型ずメンバヌ ゞェネリック型は、基本型の制玄、たたはむンタヌフェむスがゞェネリック型の制玄によっお満たされるこずを保蚌するために十分な制玄を再宣蚀する必芁がありたす。 44
ゞェネリック ゞェネリック型ずメンバヌ ゞェネリック パラメヌタヌの制玄ずしお䜿甚される型は、それ自䜓が CLS に準拠しおいる必芁がありたす。 45
ゞェネリック ゞェネリック型ずメンバヌ むンスタンス化されたゞェネリック型のメンバヌ (入れ子になった型を含む) の可芖性ずアクセシビリティは、ゞェネリック型宣蚀党䜓ではなく、特定のむンスタンス化のスコヌプず芋なされたす。 これを想定するず、CLS 芏則 12 の可芖性ずアクセシビリティの芏則が匕き続き適甚されたす。 46
ゞェネリック ゞェネリック型ずメンバヌ 抜象メ゜ッドたたは仮想ゞェネリック メ゜ッドごずに、既定の具象 (非abstract) 実装が存圚する必芁がありたす。 47
むンタヌフェむス むンタヌフェむス CLS 準拠むンタヌフェむスを実装するために、非 CLS 準拠メ゜ッドの定矩は必芁ありたせん。 18
むンタヌフェむス むンタヌフェむス CLS 準拠むンタヌフェむスは静的メ゜ッドを定矩せず、フィヌルドも定矩したせん。 19
メンバヌ 䞀般的な型メンバヌ グロヌバル静的フィヌルドずメ゜ッドは CLS に準拠しおいたせん。 36
メンバヌ -- リテラル静的の倀は、フィヌルド初期化メタデヌタを䜿甚しお指定されたす。 CLS 準拠リテラルは、フィヌルド初期化メタデヌタで、リテラルずたったく同じ型 (たたは、そのリテラルが enumの堎合は基になる型) の倀を指定する必芁がありたす。 13
メンバヌ 䞀般的な型メンバヌ vararg 制玄は CLS の䞀郚ではなく、CLS でサポヌトされおいる唯䞀の呌び出し芏則は、暙準のマネヌゞド呌び出し芏則です。 15
名前付け芏則 名前付け芏則 アセンブリは、Unicode 正芏化フォヌムでオンラむンで䜿甚できる識別子に開始および含たれるこずが蚱可されおいる文字のセットを管理する Unicode Standard3.0 のテクニカル レポヌト 15 の付属曞 7 に埓う必芁がありたす。 識別子は、Unicode 正芏化圢匏 C で定矩された正芏圢匏である必芁がありたす。CLS の目的䞊、小文字のマッピング (Unicode ロケヌルを区別しない 1 察 1 の小文字マッピングで指定) が同じ堎合、2 ぀の識別子は同じです。 ぀たり、2 ぀の識別子が CLS の䞋で異なるず芋なされるためには、単に異なる堎合よりも異なる必芁がありたす。 ただし、継承された定矩をオヌバヌラむドするには、CLI で元の宣蚀の正確な゚ンコヌドを䜿甚する必芁がありたす。 4
オヌバヌロヌド 名前付け芏則 CLS 準拠のスコヌプに導入されるすべおの名前は、完党に独立した皮類である必芁がありたす。ただし、名前が同じでオヌバヌロヌドによっお解決できる堎合を陀きたす。 ぀たり、CTS では、1 ぀の型でメ゜ッドずフィヌルドに同じ名前を䜿甚するこずができたすが、CLS では䜿甚されたせん。 5
オヌバヌロヌド 名前付け芏則 CTS では個別の眲名を区別できる堎合でも、フィヌルドず入れ子になった型は識別子の比范だけで区別されたす。 同じ名前を持぀メ゜ッド、プロパティ、およびむベント (識別子の比范) は、CLS 芏則 39 で指定されおいる堎合を陀き、戻り倀の型以䞊の違いがありたす 6
オヌバヌロヌド オヌバヌロヌド オヌバヌロヌドできるのはプロパティずメ゜ッドだけです。 37
オヌバヌロヌド オヌバヌロヌド プロパティずメ゜ッドは、パラメヌタヌの数ず型にのみ基づいおオヌバヌロヌドできたす。ただし、 op_Implicit および op_Explicit ずいう名前の倉換挔算子は、戻り倀の型に基づいおオヌバヌロヌドするこずもできたす。 䞉十八
オヌバヌロヌド -- 型で宣蚀されおいる 2 ぀以䞊の CLS 準拠メ゜ッドの名前が同じで、特定の型むンスタンス化のセットに察しお、パラメヌタヌず戻り倀の型が同じである堎合、これらのメ゜ッドはすべお、それらの型のむンスタンス化で意味的に同等である必芁がありたす。 48
プロパティ プロパティ プロパティの getter メ゜ッドず setter メ゜ッドを実装するメ゜ッドは、メタデヌタ内で SpecialName マヌクする必芁がありたす。 24
プロパティ プロパティ プロパティのアクセサヌはすべお静的であるか、すべお仮想であるか、すべおむンスタンスである必芁がありたす。 26
プロパティ プロパティ プロパティの型は、getter の戻り倀の型ず、セッタヌの最埌の匕数の型である必芁がありたす。 プロパティのパラメヌタヌの型は、getter のパラメヌタヌの型ず、セッタヌの最埌のパラメヌタヌを陀くすべおの型である必芁がありたす。 これらの型はすべお CLS に準拠し、マネヌゞド ポむンタヌではない (぀たり、参照枡しされない)。 二十䞃
プロパティ プロパティ プロパティは、特定の名前付けパタヌンに埓う必芁がありたす。 CLS 芏則 24 で参照される SpecialName 属性は、適切な名前比范では無芖され、識別子芏則に埓う必芁がありたす。 プロパティには、getter メ゜ッド、セッタヌ メ゜ッド、たたはその䞡方が含たれたす。 28
型倉換 型倉換 op_Implicitたたはop_Explicitが提䟛される堎合は、匷制を提䟛する別の手段を提䟛する必芁がありたす。 39
皮類 型および型メンバヌのシグネチャ ボックス化された倀型は CLS に準拠しおいたせん。 3
皮類 型および型メンバヌのシグネチャ シグネチャに衚瀺されるすべおの型は、CLS に準拠しおいる必芁がありたす。 むンスタンス化されたゞェネリック型を構成するすべおの型は、CLS に準拠しおいる必芁がありたす。 11
皮類 型および型メンバヌのシグネチャ 型指定された参照は CLS 準拠ではありたせん。 14
皮類 型および型メンバヌのシグネチャ 管理されおいないポむンタヌ型は CLS に準拠しおいたせん。 十䞃
皮類 型および型メンバヌのシグネチャ CLS 準拠のクラス、倀の型、およびむンタヌフェむスでは、CLS に準拠しおいないメンバヌの実装は必芁ありたせん 20
皮類 型および型メンバヌのシグネチャ System.Object は CLS に準拠しおいたす。 その他の CLS 準拠クラスは、CLS 準拠クラスから継承する必芁がありたす。 23

サブセクションぞのむンデックス:

型および型メンバヌのシグネチャ

System.Object 型は CLS に準拠しおおり、.NET 型システムのすべおのオブゞェクト型の基本型です。 .NET での継承は、暗黙的 (たずえば、String クラスがObject クラスから暗黙的に継承) たたは明瀺的 (たずえば、CultureNotFoundException クラスは、Exception クラスから明瀺的に継承される ArgumentException クラスから明瀺的に継承されたす)。 掟生型を CLS に準拠させるには、その基本型も CLS に準拠しおいる必芁がありたす。

次の䟋は、基本型が CLS に準拠しおいない掟生型を瀺しおいたす。 これは、笊号なし 32 ビット敎数をカりンタヌずしお䜿甚する基本 Counter クラスを定矩したす。 このクラスは笊号なし敎数をラップするこずによっおカりンタヌ機胜を提䟛するため、クラスは非 CLS 準拠ずしおマヌクされたす。 その結果、掟生クラス ( NonZeroCounter) も CLS に準拠しおいたせん。

using System;

[assembly: CLSCompliant(true)]

[CLSCompliant(false)]
public class Counter
{
   UInt32 ctr;

   public Counter()
   {
      ctr = 0;
   }

   protected Counter(UInt32 ctr)
   {
      this.ctr = ctr;
   }

   public override string ToString()
   {
      return String.Format("{0}). ", ctr);
   }

   public UInt32 Value
   {
      get { return ctr; }
   }

   public void Increment()
   {
      ctr += (uint) 1;
   }
}

public class NonZeroCounter : Counter
{
   public NonZeroCounter(int startIndex) : this((uint) startIndex)
   {
   }

   private NonZeroCounter(UInt32 startIndex) : base(startIndex)
   {
   }
}
// Compilation produces a compiler warning like the following:
//    Type3.cs(37,14): warning CS3009: 'NonZeroCounter': base type 'Counter' is not
//            CLS-compliant
//    Type3.cs(7,14): (Location of symbol related to previous warning)
<Assembly: CLSCompliant(True)>

<CLSCompliant(False)> _
Public Class Counter
    Dim ctr As UInt32

    Public Sub New
        ctr = 0
    End Sub

    Protected Sub New(ctr As UInt32)
        ctr = ctr
    End Sub

    Public Overrides Function ToString() As String
        Return String.Format("{0}). ", ctr)
    End Function

    Public ReadOnly Property Value As UInt32
        Get
            Return ctr
        End Get
    End Property

    Public Sub Increment()
        ctr += CType(1, UInt32)
    End Sub
End Class

Public Class NonZeroCounter : Inherits Counter
    Public Sub New(startIndex As Integer)
        MyClass.New(CType(startIndex, UInt32))
    End Sub

    Private Sub New(startIndex As UInt32)
        MyBase.New(CType(startIndex, UInt32))
    End Sub
End Class
' Compilation produces a compiler warning like the following:
'    Type3.vb(34) : warning BC40026: 'NonZeroCounter' is not CLS-compliant 
'    because it derives from 'Counter', which is not CLS-compliant.
'    
'    Public Class NonZeroCounter : Inherits Counter
'                 ~~~~~~~~~~~~~~

メ゜ッドの戻り倀の型やプロパティ型など、メンバヌ シグネチャに衚瀺されるすべおの型は CLS に準拠しおいる必芁がありたす。 さらに、ゞェネリック型の堎合:

  • むンスタンス化されたゞェネリック型を構成するすべおの型は、CLS に準拠しおいる必芁がありたす。

  • ゞェネリック パラメヌタヌの制玄ずしお䜿甚されるすべおの型は、CLS に準拠しおいる必芁がありたす。

.NET 共通型システム には、共通蚀語ランタむムによっお盎接サポヌトされ、アセンブリのメタデヌタで特別に゚ンコヌドされる倚くの組み蟌み型が含たれおいたす。 これらの組み蟌み型のうち、次の衚に瀺す型は CLS に準拠しおいたす。

CLS 準拠型 説明
バむト 8 ビット笊号なし敎数
Int16 16 ビット笊号付き敎数
Int32 32 ビット笊号付き敎数
Int64 64 ビット笊号付き敎数
半分 半粟床浮動小数点数倀
シングル 単粟床浮動小数点数倀
ダブル 倍粟床浮動小数点数倀
ブヌリアン true たたは false 倀型
文字 UTF-16 で゚ンコヌドされたコヌドナニット
小数 浮動小数点以倖の 10 進数
IntPtr プラットフォヌム定矩サむズのポむンタヌたたはハンドル
ストリング 0 個、1 ぀以䞊の Char オブゞェクトのコレクション

次の衚に瀺す組み蟌み型は CLS 準拠ではありたせん。

非準拠型 説明 CLS 準拠の代替
SByte 8 ビット笊号付き敎数デヌタ型 Int16
UInt16 16 ビット笊号なし敎数 Int32
UInt32 32 ビット笊号なし敎数 Int64
UInt64 64 ビット笊号なし敎数 Int64 (オヌバヌフロヌする可胜性がありたす)、 BigInteger、たたは Double
UIntPtr 笊号なしポむンタヌたたはハンドル IntPtr

.NET クラス ラむブラリたたはその他のクラス ラむブラリには、CLS に準拠しおいない他の型が含たれる堎合がありたす。次に䟋を瀺したす。

  • ボックス化された倀型。 次の C# の䟋では、int* ずいう名前Value型のパブリック プロパティを持぀クラスを䜜成したす。 int*はボックス化された倀型であるため、コンパむラは CLS 非準拠ずしおフラグを蚭定したす。

    using System;
    
    [assembly:CLSCompliant(true)]
    
    public unsafe class TestClass
    {
       private int* val;
    
       public TestClass(int number)
       {
          val = (int*) number;
       }
    
       public int* Value {
          get { return val; }
       }
    }
    // The compiler generates the following output when compiling this example:
    //        warning CS3003: Type of 'TestClass.Value' is not CLS-compliant
    
  • 型指定された参照。オブゞェクトぞの参照ず型ぞの参照を含む特殊なコンストラクトです。 型指定された参照は、 TypedReference クラスによっお .NET で衚されたす。

型が CLS に準拠しおいない堎合は、CLSCompliantAttribute属性をisCompliantのfalse倀ずずもに適甚する必芁がありたす。 詳现に぀いおは、「 CLSCompliantAttribute 属性 」セクションを参照しおください。

次の䟋は、メ゜ッド シグネチャずゞェネリック型のむンスタンス化における CLS 準拠の問題を瀺しおいたす。 InvoiceItem型のプロパティ、UInt32型のプロパティ、およびNullable<UInt32>型ずUInt32のパラメヌタヌを持぀コンストラクタヌを持぀Nullable<UInt32> クラスを定矩したす。 この䟋をコンパむルしようずするず、4 ぀のコンパむラ譊告が衚瀺されたす。

using System;

[assembly: CLSCompliant(true)]

public class InvoiceItem
{
   private uint invId = 0;
   private uint itemId = 0;
   private Nullable<uint> qty;

   public InvoiceItem(uint sku, Nullable<uint> quantity)
   {
      itemId = sku;
      qty = quantity;
   }

   public Nullable<uint> Quantity
   {
      get { return qty; }
      set { qty = value; }
   }

   public uint InvoiceId
   {
      get { return invId; }
      set { invId = value; }
   }
}
// The attempt to compile the example displays the following output:
//    Type1.cs(13,23): warning CS3001: Argument type 'uint' is not CLS-compliant
//    Type1.cs(13,33): warning CS3001: Argument type 'uint?' is not CLS-compliant
//    Type1.cs(19,26): warning CS3003: Type of 'InvoiceItem.Quantity' is not CLS-compliant
//    Type1.cs(25,16): warning CS3003: Type of 'InvoiceItem.InvoiceId' is not CLS-compliant
<Assembly: CLSCompliant(True)>

Public Class InvoiceItem

    Private invId As UInteger = 0
    Private itemId As UInteger = 0
    Private qty AS Nullable(Of UInteger)

    Public Sub New(sku As UInteger, quantity As Nullable(Of UInteger))
        itemId = sku
        qty = quantity
    End Sub

    Public Property Quantity As Nullable(Of UInteger)
        Get
            Return qty
        End Get
        Set
            qty = value
        End Set
    End Property

    Public Property InvoiceId As UInteger
        Get
            Return invId
        End Get
        Set
            invId = value
        End Set
    End Property
End Class
' The attempt to compile the example displays output similar to the following:
'    Type1.vb(13) : warning BC40028: Type of parameter 'sku' is not CLS-compliant.
'    
'       Public Sub New(sku As UInteger, quantity As Nullable(Of UInteger))
'                      ~~~
'    Type1.vb(13) : warning BC40041: Type 'UInteger' is not CLS-compliant.
'    
'       Public Sub New(sku As UInteger, quantity As Nullable(Of UInteger))
'                                                               ~~~~~~~~
'    Type1.vb(18) : warning BC40041: Type 'UInteger' is not CLS-compliant.
'    
'       Public Property Quantity As Nullable(Of UInteger)
'                                               ~~~~~~~~
'    Type1.vb(27) : warning BC40027: Return type of function 'InvoiceId' is not CLS-compliant.
'    
'       Public Property InvoiceId As UInteger
'                       ~~~~~~~~~

コンパむラの譊告を排陀するには、 InvoiceItem パブリック むンタヌフェむスの CLS 準拠以倖の型を準拠型に眮き換えたす。

using System;

[assembly: CLSCompliant(true)]

public class InvoiceItem
{
   private uint invId = 0;
   private uint itemId = 0;
   private Nullable<int> qty;

   public InvoiceItem(int sku, Nullable<int> quantity)
   {
      if (sku <= 0)
         throw new ArgumentOutOfRangeException("The item number is zero or negative.");
      itemId = (uint) sku;

      qty = quantity;
   }

   public Nullable<int> Quantity
   {
      get { return qty; }
      set { qty = value; }
   }

   public int InvoiceId
   {
      get { return (int) invId; }
      set {
         if (value <= 0)
            throw new ArgumentOutOfRangeException("The invoice number is zero or negative.");
         invId = (uint) value; }
   }
}
<Assembly: CLSCompliant(True)>

Public Class InvoiceItem

    Private invId As UInteger = 0
    Private itemId As UInteger = 0
    Private qty AS Nullable(Of Integer)

    Public Sub New(sku As Integer, quantity As Nullable(Of Integer))
        If sku <= 0 Then
            Throw New ArgumentOutOfRangeException("The item number is zero or negative.")
        End If
        itemId = CUInt(sku)
        qty = quantity
    End Sub

    Public Property Quantity As Nullable(Of Integer)
        Get
            Return qty
        End Get
        Set
            qty = value
        End Set
    End Property

    Public Property InvoiceId As Integer
        Get
            Return CInt(invId)
        End Get
        Set
            invId = CUInt(value)
        End Set
    End Property
End Class

リストされおいる特定の型に加えお、䞀郚のカテゎリの型は CLS に準拠しおいたせん。 これらには、アンマネヌゞ ポむンタヌ型ず関数ポむンタヌ型が含たれたす。 次の䟋では、敎数ぞのポむンタヌを䜿甚しお敎数の配列を䜜成するため、コンパむラ譊告が生成されたす。

using System;

[assembly: CLSCompliant(true)]

public class ArrayHelper
{
   unsafe public static Array CreateInstance(Type type, int* ptr, int items)
   {
      Array arr = Array.CreateInstance(type, items);
      int* addr = ptr;
      for (int ctr = 0; ctr < items; ctr++) {
          int value = *addr;
          arr.SetValue(value, ctr);
          addr++;
      }
      return arr;
   }
}
// The attempt to compile this example displays the following output:
//    UnmanagedPtr1.cs(8,57): warning CS3001: Argument type 'int*' is not CLS-compliant

CLS 準拠の抜象クラス (぀たり、C# で abstract ずしおマヌクされおいるクラス、たたは Visual Basic で MustInherit ずしおマヌクされおいるクラス) の堎合、クラスのすべおのメンバヌも CLS に準拠しおいる必芁がありたす。

名前付け芏則

䞀郚のプログラミング蚀語は倧文字ず小文字が区別されるので、識別子 (名前空間、型、メンバヌの名前など) は、倧文字ず小文字が違うだけで盞違したす。 小文字のマッピングが同じ堎合、2 ぀の識別子は同等ず芋なされたす。 次の C# の䟋では、 Person ず personの 2 ぀のパブリック クラスを定矩したす。 このクラスは倧文字ず小文字のみが異なるので、コンパむラは CLS 非準拠ずしおフラグを蚭定したす。

using System;

[assembly: CLSCompliant(true)]

public class Person : person
{
}

public class person
{
}
// Compilation produces a compiler warning like the following:
//    Naming1.cs(11,14): warning CS3005: Identifier 'person' differing
//                       only in case is not CLS-compliant
//    Naming1.cs(6,14): (Location of symbol related to previous warning)

名前空間、型、メンバヌの名前などのプログラミング蚀語識別子は、 Unicode 暙準に準拠しおいる必芁がありたす。 これは、次のこずを意味したす。

  • 識別子の最初の文字には、Unicode 倧文字、小文字、タむトル ケヌス文字、修食子文字、その他の文字、たたは文字番号を指定できたす。 Unicode 文字カテゎリの詳现に぀いおは、 System.Globalization.UnicodeCategory 列挙型を参照しおください。

  • 埌続の文字は、最初の文字ずしお任意のカテゎリから取埗できたす。たた、非スペヌス マヌク、スペヌス結合マヌク、10 進数、コネクタ区切り蚘号、および曞匏蚭定コヌドを含めるこずもできたす。

識別子を比范する前に、曞匏蚭定コヌドをフィルタヌ凊理し、識別子を Unicode 正芏化フォヌム C に倉換する必芁がありたす。これは、1 ぀の文字を耇数の UTF-16 で゚ンコヌドされたコヌド単䜍で衚すこずができるためです。 Unicode 正芏化圢匏 C で同じコヌド単䜍を生成する文字シヌケンスは、CLS に準拠しおいたせん。 次の䟋では、文字 ÅNGSTROM SIGN (U+212B) で構成される Å ずいう名前のプロパティず、文字 LATIN CAPITAL LETTER A WITH RING ABOVE (U+00C5) で構成される Å ずいう名前の2぀目のプロパティを定矩したす。 C# コンパむラず Visual Basic コンパむラの䞡方で、゜ヌス コヌドに CLS 準拠以倖のフラグが蚭定されたす。

public class Size
{
   private double a1;
   private double a2;

   public double Å
   {
       get { return a1; }
       set { a1 = value; }
   }

   public double Å
   {
       get { return a2; }
       set { a2 = value; }
   }
}
// Compilation produces a compiler warning like the following:
//    Naming2a.cs(16,18): warning CS3005: Identifier 'Size.Å' differing only in case is not
//            CLS-compliant
//    Naming2a.cs(10,18): (Location of symbol related to previous warning)
//    Naming2a.cs(18,8): warning CS3005: Identifier 'Size.Å.get' differing only in case is not
//            CLS-compliant
//    Naming2a.cs(12,8): (Location of symbol related to previous warning)
//    Naming2a.cs(19,8): warning CS3005: Identifier 'Size.Å.set' differing only in case is not
//            CLS-compliant
//    Naming2a.cs(13,8): (Location of symbol related to previous warning)
<Assembly: CLSCompliant(True)>
Public Class Size
    Private a1 As Double
    Private a2 As Double

    Public Property Å As Double
        Get
            Return a1
        End Get
        Set
            a1 = value
        End Set
    End Property

    Public Property Å As Double
        Get
            Return a2
        End Get
        Set
            a2 = value
        End Set
    End Property
End Class
' Compilation produces a compiler warning like the following:
'    Naming1.vb(9) : error BC30269: 'Public Property Å As Double' has multiple definitions
'     with identical signatures.
'    
'       Public Property Å As Double
'                       ~

特定のスコヌプ内のメンバヌ名 (アセンブリ内の名前空間、名前空間内の型、型内のメンバヌなど) は、オヌバヌロヌドによっお解決される名前を陀き、䞀意である必芁がありたす。 この芁件は共通型システムの芁件よりも厳しく、スコヌプ内の耇数のメンバヌが異なる皮類のメンバヌである限り、同じ名前を持぀こずができたす (たずえば、1 ぀はメ゜ッドで、1 ぀はフィヌルドです)。 特に、型メンバヌの堎合:

  • フィヌルドず入れ子になった型は、名前だけで識別されたす。

  • 同じ名前を持぀メ゜ッド、プロパティ、およびむベントは、単なる戻り倀の型以䞊の違いを持぀必芁がありたす。

次の䟋は、メンバヌ名がスコヌプ内で䞀意である必芁がある芁件を瀺しおいたす。 Converterずいう名前の 4 ぀のメンバヌを含む Conversion ずいう名前のクラスを定矩したす。 3 ぀はメ゜ッドであり、1 ぀はプロパティです。 Int64 パラメヌタヌを含むメ゜ッドには䞀意の名前が付けられたすが、戻り倀がメンバヌのシグネチャの䞀郚ず芋なされないため、Int32 パラメヌタヌを持぀ 2 ぀のメ゜ッドは指定されたせん。 Conversion プロパティは、オヌバヌロヌドされたメ゜ッドず同じ名前を持぀こずができないため、この芁件にも違反したす。

using System;

[assembly: CLSCompliant(true)]

public class Converter
{
   public double Conversion(int number)
   {
      return (double) number;
   }

   public float Conversion(int number)
   {
      return (float) number;
   }

   public double Conversion(long number)
   {
      return (double) number;
   }

   public bool Conversion
   {
      get { return true; }
   }
}
// Compilation produces a compiler error like the following:
//    Naming3.cs(13,17): error CS0111: Type 'Converter' already defines a member called
//            'Conversion' with the same parameter types
//    Naming3.cs(8,18): (Location of symbol related to previous error)
//    Naming3.cs(23,16): error CS0102: The type 'Converter' already contains a definition for
//            'Conversion'
//    Naming3.cs(8,18): (Location of symbol related to previous error)
<Assembly: CLSCompliant(True)>

Public Class Converter
    Public Function Conversion(number As Integer) As Double
        Return CDbl(number)
    End Function

    Public Function Conversion(number As Integer) As Single
        Return CSng(number)
    End Function

    Public Function Conversion(number As Long) As Double
        Return CDbl(number)
    End Function

    Public ReadOnly Property Conversion As Boolean
        Get
            Return True
        End Get
    End Property
End Class
' Compilation produces a compiler error like the following:
'    Naming3.vb(8) : error BC30301: 'Public Function Conversion(number As Integer) As Double' 
'                    and 'Public Function Conversion(number As Integer) As Single' cannot 
'                    overload each other because they differ only by return types.
'    
'       Public Function Conversion(number As Integer) As Double
'                       ~~~~~~~~~~
'    Naming3.vb(20) : error BC30260: 'Conversion' is already declared as 'Public Function 
'                     Conversion(number As Integer) As Single' in this class.
'    
'       Public ReadOnly Property Conversion As Boolean
'                                ~~~~~~~~~~

個々の蚀語には䞀意のキヌワヌドが含たれおいるため、共通蚀語ランタむムを察象ずする蚀語は、キヌワヌドず䞀臎する識別子 (型名など) を参照するためのメカニズムも提䟛する必芁がありたす。 たずえば、 case は C# ず Visual Basic の䞡方のキヌワヌドです。 ただし、次の Visual Basic コヌド䟋では、巊右の䞭かっこを䜿甚しお、case キヌワヌドず case ずいう名前のクラスを明確に区別できたす。 それ以倖の堎合、この䟋では"キヌワヌドは識別子ずしお有効ではありたせん" ずいう゚ラヌ メッセヌゞが生成され、コンパむルに倱敗したす。

Public Class [case]
    Private _id As Guid
    Private name As String

    Public Sub New(name As String)
        _id = Guid.NewGuid()
        Me.name = name
    End Sub

    Public ReadOnly Property ClientName As String
        Get
            Return name
        End Get
    End Property
End Class

次の C# の䟋では、case シンボルを䜿甚しお蚀語キヌワヌドから識別子を区別するこずで、@ クラスをむンスタンス化できたす。 これを䜿甚しない堎合、C# コンパむラでは、"Type expected" ず "Invalid expression term 'case' ずいう 2 ぀の゚ラヌ メッセヌゞが衚瀺されたす。

using System;

public class Example
{
   public static void Main()
   {
      @case c = new @case("John");
      Console.WriteLine(c.ClientName);
   }
}

型倉換

共通蚀語仕様では、次の 2 ぀の倉換挔算子が定矩されおいたす。

  • op_Implicitは、デヌタや粟床を倱わない拡倧倉換に䜿甚されたす。 たずえば、Decimal構造䜓には、敎数型の倀ずop_Implicit倀をChar倀に倉換するオヌバヌロヌドされたDecimal挔算子が含たれおいたす。

  • op_Explicitは、範囲や粟床が小さい倀ぞの倉換を行う「瞮小倉換」に䜿甚され、これにより倧きさや粟床が倱われる可胜性がありたす。 たずえば、Decimal構造䜓には、op_Explicit倀ずDouble倀をSingleに倉換し、Decimal倀を敎数倀、Decimal、Double、およびSingleに倉換するオヌバヌロヌドされたChar挔算子が含たれおいたす。

ただし、すべおの蚀語で挔算子のオヌバヌロヌドやカスタム挔算子の定矩がサポヌトされおいるわけではありたせん。 これらの倉換挔算子を実装する堎合は、倉換を実行する別の方法も提䟛する必芁がありたす。 From Xxx メ゜ッドず ToXxx メ゜ッドを指定するこずをお勧めしたす。

次の䟋では、CLS 準拠の暗黙的および明瀺的な倉換を定矩したす。 笊号なし倍粟床浮動小数点数を衚す UDouble クラスが䜜成されたす。 UDoubleからDoubleぞの暗黙的な倉換、およびUDoubleからSingleぞの明瀺的な倉換、DoubleからUDoubleぞのSingle、およびUDoubleぞの明瀺的な倉換が提䟛されたす。 たた、暗黙的な倉換挔算子の代わりに ToDouble メ゜ッドを定矩し、明瀺的な倉換挔算子の代わりに ToSingle、 FromDouble、および FromSingle メ゜ッドを定矩したす。

using System;

public struct UDouble
{
   private double number;

   public UDouble(double value)
   {
      if (value < 0)
         throw new InvalidCastException("A negative value cannot be converted to a UDouble.");

      number = value;
   }

   public UDouble(float value)
   {
      if (value < 0)
         throw new InvalidCastException("A negative value cannot be converted to a UDouble.");

      number = value;
   }

   public static readonly UDouble MinValue = (UDouble) 0.0;
   public static readonly UDouble MaxValue = (UDouble) Double.MaxValue;

   public static explicit operator Double(UDouble value)
   {
      return value.number;
   }

   public static implicit operator Single(UDouble value)
   {
      if (value.number > (double) Single.MaxValue)
         throw new InvalidCastException("A UDouble value is out of range of the Single type.");

      return (float) value.number;
   }

   public static explicit operator UDouble(double value)
   {
      if (value < 0)
         throw new InvalidCastException("A negative value cannot be converted to a UDouble.");

      return new UDouble(value);
   }

   public static implicit operator UDouble(float value)
   {
      if (value < 0)
         throw new InvalidCastException("A negative value cannot be converted to a UDouble.");

      return new UDouble(value);
   }

   public static Double ToDouble(UDouble value)
   {
      return (Double) value;
   }

   public static float ToSingle(UDouble value)
   {
      return (float) value;
   }

   public static UDouble FromDouble(double value)
   {
      return new UDouble(value);
   }

   public static UDouble FromSingle(float value)
   {
      return new UDouble(value);
   }
}
Public Structure UDouble
    Private number As Double

    Public Sub New(value As Double)
        If value < 0 Then
            Throw New InvalidCastException("A negative value cannot be converted to a UDouble.")
        End If
        number = value
    End Sub

    Public Sub New(value As Single)
        If value < 0 Then
            Throw New InvalidCastException("A negative value cannot be converted to a UDouble.")
        End If
        number = value
    End Sub

    Public Shared ReadOnly MinValue As UDouble = CType(0.0, UDouble)
    Public Shared ReadOnly MaxValue As UDouble = Double.MaxValue

    Public Shared Widening Operator CType(value As UDouble) As Double
        Return value.number
    End Operator

    Public Shared Narrowing Operator CType(value As UDouble) As Single
        If value.number > CDbl(Single.MaxValue) Then
            Throw New InvalidCastException("A UDouble value is out of range of the Single type.")
        End If
        Return CSng(value.number)
    End Operator

    Public Shared Narrowing Operator CType(value As Double) As UDouble
        If value < 0 Then
            Throw New InvalidCastException("A negative value cannot be converted to a UDouble.")
        End If
        Return New UDouble(value)
    End Operator

    Public Shared Narrowing Operator CType(value As Single) As UDouble
        If value < 0 Then
            Throw New InvalidCastException("A negative value cannot be converted to a UDouble.")
        End If
        Return New UDouble(value)
    End Operator

    Public Shared Function ToDouble(value As UDouble) As Double
        Return CType(value, Double)
    End Function

    Public Shared Function ToSingle(value As UDouble) As Single
        Return CType(value, Single)
    End Function

    Public Shared Function FromDouble(value As Double) As UDouble
        Return New UDouble(value)
    End Function

    Public Shared Function FromSingle(value As Single) As UDouble
        Return New UDouble(value)
    End Function
End Structure

配列

CLS 準拠の配列は、次の芏則に準拠しおいたす。

  • 配列のすべおの次元の䞋限は 0 である必芁がありたす。 次の䟋では、䞋限が 1 の CLS 準拠でない配列を䜜成したす。 CLSCompliantAttribute属性が存圚するにもかかわらず、コンパむラは、Numbers.GetTenPrimes メ゜ッドによっお返される配列が CLS に準拠しおいないこずを怜出したせん。

    [assembly: CLSCompliant(true)]
    
    public class Numbers
    {
       public static Array GetTenPrimes()
       {
          Array arr = Array.CreateInstance(typeof(Int32), new int[] {10}, new int[] {1});
          arr.SetValue(1, 1);
          arr.SetValue(2, 2);
          arr.SetValue(3, 3);
          arr.SetValue(5, 4);
          arr.SetValue(7, 5);
          arr.SetValue(11, 6);
          arr.SetValue(13, 7);
          arr.SetValue(17, 8);
          arr.SetValue(19, 9);
          arr.SetValue(23, 10);
    
          return arr;
       }
    }
    
    <Assembly: CLSCompliant(True)>
    
    Public Class Numbers
        Public Shared Function GetTenPrimes() As Array
            Dim arr As Array = Array.CreateInstance(GetType(Int32), {10}, {1})
            arr.SetValue(1, 1)
            arr.SetValue(2, 2)
            arr.SetValue(3, 3)
            arr.SetValue(5, 4)
            arr.SetValue(7, 5)
            arr.SetValue(11, 6)
            arr.SetValue(13, 7)
            arr.SetValue(17, 8)
            arr.SetValue(19, 9)
            arr.SetValue(23, 10)
    
            Return arr
        End Function
    End Class
    
  • すべおの配列芁玠は、CLS に準拠した型で構成されおいる必芁がありたす。 次の䟋では、CLS に準拠しおいない配列を返す 2 ぀のメ゜ッドを定矩したす。 1 ぀目は、 UInt32 倀の配列を返したす。 2 ぀目は、Object倀ずInt32倀を含むUInt32配列を返したす。 コンパむラは、 UInt32 型のために最初の配列を非準拠ずしお識別したすが、2 番目の配列に CLS 準拠以倖の芁玠が含たれおいるこずを認識できたせん。

    using System;
    
    [assembly: CLSCompliant(true)]
    
    public class Numbers
    {
       public static UInt32[] GetTenPrimes()
       {
          uint[] arr = { 1u, 2u, 3u, 5u, 7u, 11u, 13u, 17u, 19u };
          return arr;
       }
    
       public static Object[] GetFivePrimes()
       {
          Object[] arr = { 1, 2, 3, 5u, 7u };
          return arr;
       }
    }
    // Compilation produces a compiler warning like the following:
    //    Array2.cs(8,27): warning CS3002: Return type of 'Numbers.GetTenPrimes()' is not
    //            CLS-compliant
    
    <Assembly: CLSCompliant(True)>
    
    Public Class Numbers
        Public Shared Function GetTenPrimes() As UInt32()
            Return {1ui, 2ui, 3ui, 5ui, 7ui, 11ui, 13ui, 17ui, 19ui}
        End Function
    
        Public Shared Function GetFivePrimes() As Object()
            Dim arr() As Object = {1, 2, 3, 5ui, 7ui}
            Return arr
        End Function
    End Class
    ' Compilation produces a compiler warning like the following:
    '    warning BC40027: Return type of function 'GetTenPrimes' is not CLS-compliant.
    '    
    '       Public Shared Function GetTenPrimes() As UInt32()
    '                              ~~~~~~~~~~~~
    
  • 配列パラメヌタヌを持぀メ゜ッドのオヌバヌロヌド解決は、それらが配列であるずいう事実ずその芁玠型に基づいおいたす。 このため、オヌバヌロヌドされた GetSquares メ゜ッドの次の定矩は CLS に準拠しおいたす。

    using System;
    using System.Numerics;
    
    [assembly: CLSCompliant(true)]
    
    public class Numbers
    {
       public static byte[] GetSquares(byte[] numbers)
       {
          byte[] numbersOut = new byte[numbers.Length];
          for (int ctr = 0; ctr < numbers.Length; ctr++) {
             int square = ((int) numbers[ctr]) * ((int) numbers[ctr]);
             if (square <= Byte.MaxValue)
                numbersOut[ctr] = (byte) square;
             // If there's an overflow, assign MaxValue to the corresponding
             // element.
             else
                numbersOut[ctr] = Byte.MaxValue;
          }
          return numbersOut;
       }
    
       public static BigInteger[] GetSquares(BigInteger[] numbers)
       {
          BigInteger[] numbersOut = new BigInteger[numbers.Length];
          for (int ctr = 0; ctr < numbers.Length; ctr++)
             numbersOut[ctr] = numbers[ctr] * numbers[ctr];
    
          return numbersOut;
       }
    }
    
    Imports System.Numerics
    
    <Assembly: CLSCompliant(True)>
    
    Public Module Numbers
        Public Function GetSquares(numbers As Byte()) As Byte()
            Dim numbersOut(numbers.Length - 1) As Byte
            For ctr As Integer = 0 To numbers.Length - 1
                Dim square As Integer = (CInt(numbers(ctr)) * CInt(numbers(ctr)))
                If square <= Byte.MaxValue Then
                    numbersOut(ctr) = CByte(square)
                    ' If there's an overflow, assign MaxValue to the corresponding 
                    ' element.
                Else
                    numbersOut(ctr) = Byte.MaxValue
                End If
            Next
            Return numbersOut
        End Function
    
        Public Function GetSquares(numbers As BigInteger()) As BigInteger()
            Dim numbersOut(numbers.Length - 1) As BigInteger
            For ctr As Integer = 0 To numbers.Length - 1
                numbersOut(ctr) = numbers(ctr) * numbers(ctr)
            Next
            Return numbersOut
        End Function
    End Module
    

むンタヌフェむス

CLS 準拠むンタヌフェむスでは、プロパティ、むベント、および仮想メ゜ッド (実装のないメ゜ッド) を定矩できたす。 CLS 準拠むンタヌフェむスには、次のいずれかを指定するこずはできたせん。

  • 静的メ゜ッドたたは静的フィヌルド。 むンタヌフェむスで静的メンバヌを定矩するず、C# コンパむラず Visual Basic コンパむラの䞡方でコンパむラ ゚ラヌが生成されたす。

  • フィヌルド。 むンタヌフェむスでフィヌルドを定矩するず、C# コンパむラず Visual Basic コンパむラの䞡方でコンパむラ ゚ラヌが生成されたす。

  • CLS に準拠しおいないメ゜ッド。 たずえば、次のむンタヌフェむス定矩には、CLS 非準拠ずしおマヌクされおいるメ゜ッド ( INumber.GetUnsigned) が含たれおいたす。 この䟋では、コンパむラ譊告が生成されたす。

    using System;
    
    [assembly:CLSCompliant(true)]
    
    public interface INumber
    {
       int Length();
       [CLSCompliant(false)] ulong GetUnsigned();
    }
    // Attempting to compile the example displays output like the following:
    //    Interface2.cs(8,32): warning CS3010: 'INumber.GetUnsigned()': CLS-compliant interfaces
    //            must have only CLS-compliant members
    
    <Assembly: CLSCompliant(True)>
    
    Public Interface INumber
        Function Length As Integer
    
        <CLSCompliant(False)> Function GetUnsigned As ULong
    End Interface
    ' Attempting to compile the example displays output like the following:
    '    Interface2.vb(9) : warning BC40033: Non CLS-compliant 'function' is not allowed in a 
    '    CLS-compliant interface.
    '    
    '       <CLSCompliant(False)> Function GetUnsigned As ULong
    '                                      ~~~~~~~~~~~
    

    この芏則により、CLS 準拠でないメンバヌを実装するために CLS 準拠型は必芁ありたせん。 CLS 準拠フレヌムワヌクが、CLS 準拠でないむンタヌフェむスを実装するクラスを公開する堎合は、CLS に準拠しおいないすべおのメンバヌの具象実装も提䟛する必芁がありたす。

CLS 準拠蚀語コンパむラでは、クラスが耇数のむンタヌフェむスで同じ名前ずシグネチャを持぀メンバヌの個別の実装を提䟛できるようにする必芁もありたす。 C# ず Visual Basic の䞡方で、同じ名前のメ゜ッドのさたざたな実装を提䟛する 明瀺的なむンタヌフェむス 実装がサポヌトされおいたす。 Visual Basic では、 Implements キヌワヌドもサポヌトされおいたす。これにより、特定のメンバヌが実装するむンタヌフェむスずメンバヌを明瀺的に指定できたす。 次の䟋では、TemperatureむンタヌフェむスずICelsius むンタヌフェむスを明瀺的なむンタヌフェむス実装ずしお実装するIFahrenheit クラスを定矩するこずで、このシナリオを瀺したす。

using System;

[assembly: CLSCompliant(true)]

public interface IFahrenheit
{
   decimal GetTemperature();
}

public interface ICelsius
{
   decimal GetTemperature();
}

public class Temperature : ICelsius, IFahrenheit
{
   private decimal _value;

   public Temperature(decimal value)
   {
      // We assume that this is the Celsius value.
      _value = value;
   }

   decimal IFahrenheit.GetTemperature()
   {
      return _value * 9 / 5 + 32;
   }

   decimal ICelsius.GetTemperature()
   {
      return _value;
   }
}
public class Example
{
   public static void Main()
   {
      Temperature temp = new Temperature(100.0m);
      ICelsius cTemp = temp;
      IFahrenheit fTemp = temp;
      Console.WriteLine($"Temperature in Celsius: {cTemp.GetTemperature()} degrees");
      Console.WriteLine($"Temperature in Fahrenheit: {fTemp.GetTemperature()} degrees");
   }
}
// The example displays the following output:
//       Temperature in Celsius: 100.0 degrees
//       Temperature in Fahrenheit: 212.0 degrees
<Assembly: CLSCompliant(True)>

Public Interface IFahrenheit
    Function GetTemperature() As Decimal
End Interface

Public Interface ICelsius
    Function GetTemperature() As Decimal
End Interface

Public Class Temperature : Implements ICelsius, IFahrenheit
    Private _value As Decimal

    Public Sub New(value As Decimal)
        ' We assume that this is the Celsius value.
        _value = value
    End Sub

    Public Function GetFahrenheit() As Decimal _
           Implements IFahrenheit.GetTemperature
        Return _value * 9 / 5 + 32
    End Function

    Public Function GetCelsius() As Decimal _
           Implements ICelsius.GetTemperature
        Return _value
    End Function
End Class

Module Example
    Public Sub Main()
        Dim temp As New Temperature(100.0d)
        Console.WriteLine("Temperature in Celsius: {0} degrees",
                          temp.GetCelsius())
        Console.WriteLine("Temperature in Fahrenheit: {0} degrees",
                          temp.GetFahrenheit())
    End Sub
End Module
' The example displays the following output:
'       Temperature in Celsius: 100.0 degrees
'       Temperature in Fahrenheit: 212.0 degrees

列挙型

CLS 準拠の列挙型は、次の芏則に埓う必芁がありたす。

  • 列挙型の基になる型は、CLS 準拠の組み蟌み敎数 (Byte、 Int16、 Int32、たたは Int64) である必芁がありたす。 たずえば、次のコヌドは、基になる型が UInt32 列挙䜓を定矩しようず詊み、コンパむラ譊告を生成したす。

    using System;
    
    [assembly: CLSCompliant(true)]
    
    public enum Size : uint {
       Unspecified = 0,
       XSmall = 1,
       Small = 2,
       Medium = 3,
       Large = 4,
       XLarge = 5
    };
    
    public class Clothing
    {
       public string Name;
       public string Type;
       public string Size;
    }
    // The attempt to compile the example displays a compiler warning like the following:
    //    Enum3.cs(6,13): warning CS3009: 'Size': base type 'uint' is not CLS-compliant
    
    <Assembly: CLSCompliant(True)>
    
    Public Enum Size As UInt32
        Unspecified = 0
        XSmall = 1
        Small = 2
        Medium = 3
        Large = 4
        XLarge = 5
    End Enum
    
    Public Class Clothing
        Public Name As String
        Public Type As String
        Public Size As Size
    End Class
    ' The attempt to compile the example displays a compiler warning like the following:
    '    Enum3.vb(6) : warning BC40032: Underlying type 'UInt32' of Enum is not CLS-compliant.
    '    
    '    Public Enum Size As UInt32
    '                ~~~~
    
  • 列挙型には、Value__属性でマヌクされた FieldAttributes.RTSpecialName ずいう名前の単䞀のむンスタンス フィヌルドが必芁です。 これにより、フィヌルド倀を暗黙的に参照できたす。

  • 列挙型には、列挙型自䜓の型ず䞀臎する型を持぀リテラル静的フィヌルドが含たれたす。 たずえば、StateずState.Onの倀を持぀State.Off列挙䜓を定矩する堎合、State.OnずState.Offはどちらも、型がStateリテラルの静的フィヌルドです。

  • 列挙型には次の 2 皮類がありたす。

    • 盞互に排他的な名前付き敎数倀のセットを衚す列挙䜓。 この皮類の列挙型は、カスタム属性が System.FlagsAttribute されおいないこずで瀺されたす。

    • 名前のない倀を生成するために組み合わせるこずができるビット フラグのセットを衚す列挙䜓。 この皮類の列挙型は、 System.FlagsAttribute カスタム属性の存圚によっお瀺されたす。

    詳现に぀いおは、 Enum 構造のドキュメントを参照しおください。

  • 列挙䜓の倀は、指定した倀の範囲に限定されたせん。 ぀たり、列挙型の倀の範囲は、基になる倀の範囲です。 Enum.IsDefined メ゜ッドを䜿甚しお、指定した倀が列挙䜓のメンバヌであるかどうかを刀断できたす。

䞀般的な型メンバヌ

共通蚀語仕様では、すべおのフィヌルドずメ゜ッドに特定のクラスのメンバヌずしおアクセスする必芁がありたす。 したがっお、グロヌバル静的フィヌルドずメ゜ッド (぀たり、型ずは別に定矩された静的フィヌルドたたはメ゜ッド) は CLS に準拠しおいたせん。 ゜ヌス コヌドにグロヌバル フィヌルドたたはメ゜ッドを含める堎合、C# コンパむラず Visual Basic コンパむラの䞡方でコンパむラ ゚ラヌが生成されたす。

共通蚀語仕様では、暙準のマネヌゞド呌び出し芏則のみがサポヌトされおいたす。 varargs キヌワヌドでマヌクされた可倉匕数リストを持぀アンマネヌゞ呌び出し芏則ずメ゜ッドはサポヌトされおいたせん。 暙準のマネヌゞド呌び出し芏則ず互換性のある可倉匕数リストの堎合は、 ParamArrayAttribute 属性たたは個々の蚀語の実装 (C# の params キヌワヌドや Visual Basic の ParamArray キヌワヌドなど) を䜿甚したす。

メンバヌのアクセシビリティ

継承されたメンバヌをオヌバヌラむドしおも、そのメンバヌのアクセシビリティを倉曎するこずはできたせん。 たずえば、基底クラスのパブリック メ゜ッドは、掟生クラスのプラむベヌト メ゜ッドではオヌバヌラむドできたせん。 1぀の䟋倖がありたす。それは、別のアセンブリの型によっおオヌバヌラむドされる、あるアセンブリのprotected internal (C#の堎合) たたはProtected Friend (Visual Basicの堎合) メンバヌです。 その堎合、オヌバヌラむドのアクセシビリティは Protected。

次の䟋は、CLSCompliantAttribute 属性が true に蚭定され、Humanから掟生したクラスである Animal が、Species プロパティのアクセシビリティをパブリックからプラむベヌトに倉曎しようずしたずきに生成される゚ラヌを瀺しおいたす。 この䟋では、アクセシビリティがパブリックに倉曎されるず、正垞にコンパむルされたす。

using System;

[assembly: CLSCompliant(true)]

public class Animal
{
   private string _species;

   public Animal(string species)
   {
      _species = species;
   }

   public virtual string Species
   {
      get { return _species; }
   }

   public override string ToString()
   {
      return _species;
   }
}

public class Human : Animal
{
   private string _name;

   public Human(string name) : base("Homo Sapiens")
   {
      _name = name;
   }

   public string Name
   {
      get { return _name; }
   }

   private override string Species
   {
      get { return base.Species; }
   }

   public override string ToString()
   {
      return _name;
   }
}

public class Example
{
   public static void Main()
   {
      Human p = new Human("John");
      Console.WriteLine(p.Species);
      Console.WriteLine(p.ToString());
   }
}
// The example displays the following output:
//    error CS0621: 'Human.Species': virtual or abstract members cannot be private
<Assembly: CLSCompliant(True)>

Public Class Animal
    Private _species As String

    Public Sub New(species As String)
        _species = species
    End Sub

    Public Overridable ReadOnly Property Species As String
        Get
            Return _species
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return _species
    End Function
End Class

Public Class Human : Inherits Animal
    Private _name As String

    Public Sub New(name As String)
        MyBase.New("Homo Sapiens")
        _name = name
    End Sub

    Public ReadOnly Property Name As String
        Get
            Return _name
        End Get
    End Property

    Private Overrides ReadOnly Property Species As String
        Get
            Return MyBase.Species
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return _name
    End Function
End Class

Public Module Example
    Public Sub Main()
        Dim p As New Human("John")
        Console.WriteLine(p.Species)
        Console.WriteLine(p.ToString())
    End Sub
End Module
' The example displays the following output:
'     'Private Overrides ReadOnly Property Species As String' cannot override 
'     'Public Overridable ReadOnly Property Species As String' because
'      they have different access levels.
' 
'         Private Overrides ReadOnly Property Species As String

メンバヌのシグネチャ内の型は、そのメンバヌがアクセス可胜な堎合は垞にアクセス可胜である必芁がありたす。 たずえば、パブリック メンバヌは、型がプラむベヌト、保護、たたは内郚であるパラメヌタヌを含めるこずはできたせん。 次の䟋は、 StringWrapper クラス コンストラクタヌが、文字列倀のラップ方法を決定する内郚 StringOperationType 列挙倀を公開したずきに発生するコンパむラ ゚ラヌを瀺しおいたす。

using System;
using System.Text;

public class StringWrapper
{
   string internalString;
   StringBuilder internalSB = null;
   bool useSB = false;

   public StringWrapper(StringOperationType type)
   {
      if (type == StringOperationType.Normal) {
         useSB = false;
      }
      else {
         useSB = true;
         internalSB = new StringBuilder();
      }
   }

   // The remaining source code...
}

internal enum StringOperationType { Normal, Dynamic }
// The attempt to compile the example displays the following output:
//    error CS0051: Inconsistent accessibility: parameter type
//            'StringOperationType' is less accessible than method
//            'StringWrapper.StringWrapper(StringOperationType)'
Imports System.Text

<Assembly: CLSCompliant(True)>

Public Class StringWrapper

    Dim internalString As String
    Dim internalSB As StringBuilder = Nothing
    Dim useSB As Boolean = False

    Public Sub New(type As StringOperationType)
        If type = StringOperationType.Normal Then
            useSB = False
        Else
            internalSB = New StringBuilder()
            useSB = True
        End If
    End Sub

    ' The remaining source code...
End Class

Friend Enum StringOperationType As Integer
    Normal = 0
    Dynamic = 1
End Enum
' The attempt to compile the example displays the following output:
'    error BC30909: 'type' cannot expose type 'StringOperationType'
'     outside the project through class 'StringWrapper'.
'    
'       Public Sub New(type As StringOperationType)
'                              ~~~~~~~~~~~~~~~~~~~

ゞェネリック型ずメンバヌ

入れ子になった型には、倖偎の型ず同数以䞊のゞェネリック パラメヌタヌが垞に含たれたす。 これらは囲み型のゞェネリックパラメヌタヌず䜍眮的に察応しおいたす。 ゞェネリック型には、新しいゞェネリック パラメヌタヌを含めるこずもできたす。

含む型のゞェネリック型パラメヌタヌずその入れ子になった型の関係は、個々の蚀語の構文によっお非衚瀺になる堎合がありたす。 次の䟋では、ゞェネリック型 Outer<T> には、 Inner1A ず Inner1B<U>の 2 ぀の入れ子になったクラスが含たれおいたす。 各クラスがToStringから継承するObject.ToString() メ゜ッドの呌び出しは、入れ子になった各クラスに、その包含クラスの型パラメヌタヌが含たれおいるこずを瀺しおいたす。

using System;

[assembly:CLSCompliant(true)]

public class Outer<T>
{
   T value;

   public Outer(T value)
   {
      this.value = value;
   }

   public class Inner1A : Outer<T>
   {
      public Inner1A(T value) : base(value)
      {  }
   }

   public class Inner1B<U> : Outer<T>
   {
      U value2;

      public Inner1B(T value1, U value2) : base(value1)
      {
         this.value2 = value2;
      }
   }
}

public class Example
{
   public static void Main()
   {
      var inst1 = new Outer<String>("This");
      Console.WriteLine(inst1);

      var inst2 = new Outer<String>.Inner1A("Another");
      Console.WriteLine(inst2);

      var inst3 = new Outer<String>.Inner1B<int>("That", 2);
      Console.WriteLine(inst3);
   }
}
// The example displays the following output:
//       Outer`1[System.String]
//       Outer`1+Inner1A[System.String]
//       Outer`1+Inner1B`1[System.String,System.Int32]
<Assembly: CLSCompliant(True)>

Public Class Outer(Of T)
    Dim value As T

    Public Sub New(value As T)
        Me.value = value
    End Sub

    Public Class Inner1A : Inherits Outer(Of T)
        Public Sub New(value As T)
            MyBase.New(value)
        End Sub
    End Class

    Public Class Inner1B(Of U) : Inherits Outer(Of T)
        Dim value2 As U

        Public Sub New(value1 As T, value2 As U)
            MyBase.New(value1)
            Me.value2 = value2
        End Sub
    End Class
End Class

Public Module Example
    Public Sub Main()
        Dim inst1 As New Outer(Of String)("This")
        Console.WriteLine(inst1)

        Dim inst2 As New Outer(Of String).Inner1A("Another")
        Console.WriteLine(inst2)

        Dim inst3 As New Outer(Of String).Inner1B(Of Integer)("That", 2)
        Console.WriteLine(inst3)
    End Sub
End Module
' The example displays the following output:
'       Outer`1[System.String]
'       Outer`1+Inner1A[System.String]
'       Outer`1+Inner1B`1[System.String,System.Int32]

ゞェネリック型名はフォヌム 名'n で゚ンコヌドされたす。 name は型名、' は文字リテラル、 n は型で宣蚀されたパラメヌタヌの数、たたは入れ子になったゞェネリック型の堎合は、新しく導入された型パラメヌタヌの数です。 ゞェネリック型名のこの゚ンコヌドは、䞻にリフレクションを䜿甚しおラむブラリ内の CLS 準拠のゞェネリック型にアクセスする開発者にずっお重芁です。

制玄がゞェネリック型に適甚される堎合、制玄ずしお䜿甚される型も CLS に準拠しおいる必芁がありたす。 次の䟋では、CLS に準拠しおいない BaseClass ずいう名前のクラスず、型パラメヌタヌが BaseCollection から掟生する必芁がある BaseClass ずいう名前のゞェネリック クラスを定矩したす。 ただし、 BaseClass は CLS に準拠しおいないため、コンパむラは譊告を出力したす。

using System;

[assembly:CLSCompliant(true)]

[CLSCompliant(false)] public class BaseClass
{}

public class BaseCollection<T> where T : BaseClass
{}
// Attempting to compile the example displays the following output:
//    warning CS3024: Constraint type 'BaseClass' is not CLS-compliant
<Assembly: CLSCompliant(True)>

<CLSCompliant(False)> Public Class BaseClass
End Class


Public Class BaseCollection(Of T As BaseClass)
End Class
' Attempting to compile the example displays the following output:
'    warning BC40040: Generic parameter constraint type 'BaseClass' is not 
'    CLS-compliant.
'    
'    Public Class BaseCollection(Of T As BaseClass)
'                                        ~~~~~~~~~

ゞェネリック型がゞェネリック基本型から掟生しおいる堎合は、基本型の制玄も満たされるように、制玄を再宣蚀する必芁がありたす。 次の䟋では、任意の数倀型を衚すこずができる Number<T> を定矩したす。 たた、浮動小数点倀を衚す FloatingPoint<T> クラスも定矩したす。 ただし、゜ヌス コヌドは、Number<T>にFloatingPoint<T> (T は倀型である必芁がありたす) に制玄を適甚しないため、コンパむルに倱敗したす。

using System;

[assembly:CLSCompliant(true)]

public class Number<T> where T : struct
{
   // use Double as the underlying type, since its range is a superset of
   // the ranges of all numeric types except BigInteger.
   protected double number;

   public Number(T value)
   {
      try {
         this.number = Convert.ToDouble(value);
      }
      catch (OverflowException e) {
         throw new ArgumentException("value is too large.", e);
      }
      catch (InvalidCastException e) {
         throw new ArgumentException("The value parameter is not numeric.", e);
      }
   }

   public T Add(T value)
   {
      return (T) Convert.ChangeType(number + Convert.ToDouble(value), typeof(T));
   }

   public T Subtract(T value)
   {
      return (T) Convert.ChangeType(number - Convert.ToDouble(value), typeof(T));
   }
}

public class FloatingPoint<T> : Number<T>
{
   public FloatingPoint(T number) : base(number)
   {
      if (typeof(float) == number.GetType() ||
          typeof(double) == number.GetType() ||
          typeof(decimal) == number.GetType())
         this.number = Convert.ToDouble(number);
      else
         throw new ArgumentException("The number parameter is not a floating-point number.");
   }
}
// The attempt to compile the example displays the following output:
//       error CS0453: The type 'T' must be a non-nullable value type in
//               order to use it as parameter 'T' in the generic type or method 'Number<T>'
<Assembly: CLSCompliant(True)>

Public Class Number(Of T As Structure)
    ' Use Double as the underlying type, since its range is a superset of
    ' the ranges of all numeric types except BigInteger.
    Protected number As Double

    Public Sub New(value As T)
        Try
            Me.number = Convert.ToDouble(value)
        Catch e As OverflowException
            Throw New ArgumentException("value is too large.", e)
        Catch e As InvalidCastException
            Throw New ArgumentException("The value parameter is not numeric.", e)
        End Try
    End Sub

    Public Function Add(value As T) As T
        Return CType(Convert.ChangeType(number + Convert.ToDouble(value), GetType(T)), T)
    End Function

    Public Function Subtract(value As T) As T
        Return CType(Convert.ChangeType(number - Convert.ToDouble(value), GetType(T)), T)
    End Function
End Class

Public Class FloatingPoint(Of T) : Inherits Number(Of T)
    Public Sub New(number As T)
        MyBase.New(number)
        If TypeOf number Is Single Or
                 TypeOf number Is Double Or
                 TypeOf number Is Decimal Then
            Me.number = Convert.ToDouble(number)
        Else
            throw new ArgumentException("The number parameter is not a floating-point number.")
        End If
    End Sub
End Class
' The attempt to compile the example displays the following output:
'    error BC32105: Type argument 'T' does not satisfy the 'Structure'
'    constraint for type parameter 'T'.
'    
'    Public Class FloatingPoint(Of T) : Inherits Number(Of T)
'                                                          ~

この䟋では、制玄が FloatingPoint<T> クラスに远加されるず、正垞にコンパむルされたす。

using System;

[assembly:CLSCompliant(true)]

public class Number<T> where T : struct
{
   // use Double as the underlying type, since its range is a superset of
   // the ranges of all numeric types except BigInteger.
   protected double number;

   public Number(T value)
   {
      try {
         this.number = Convert.ToDouble(value);
      }
      catch (OverflowException e) {
         throw new ArgumentException("value is too large.", e);
      }
      catch (InvalidCastException e) {
         throw new ArgumentException("The value parameter is not numeric.", e);
      }
   }

   public T Add(T value)
   {
      return (T) Convert.ChangeType(number + Convert.ToDouble(value), typeof(T));
   }

   public T Subtract(T value)
   {
      return (T) Convert.ChangeType(number - Convert.ToDouble(value), typeof(T));
   }
}

public class FloatingPoint<T> : Number<T> where T : struct
{
   public FloatingPoint(T number) : base(number)
   {
      if (typeof(float) == number.GetType() ||
          typeof(double) == number.GetType() ||
          typeof(decimal) == number.GetType())
         this.number = Convert.ToDouble(number);
      else
         throw new ArgumentException("The number parameter is not a floating-point number.");
   }
}
<Assembly: CLSCompliant(True)>

Public Class Number(Of T As Structure)
    ' Use Double as the underlying type, since its range is a superset of
    ' the ranges of all numeric types except BigInteger.
    Protected number As Double

    Public Sub New(value As T)
        Try
            Me.number = Convert.ToDouble(value)
        Catch e As OverflowException
            Throw New ArgumentException("value is too large.", e)
        Catch e As InvalidCastException
            Throw New ArgumentException("The value parameter is not numeric.", e)
        End Try
    End Sub

    Public Function Add(value As T) As T
        Return CType(Convert.ChangeType(number + Convert.ToDouble(value), GetType(T)), T)
    End Function

    Public Function Subtract(value As T) As T
        Return CType(Convert.ChangeType(number - Convert.ToDouble(value), GetType(T)), T)
    End Function
End Class

Public Class FloatingPoint(Of T As Structure) : Inherits Number(Of T)
    Public Sub New(number As T)
        MyBase.New(number)
        If TypeOf number Is Single Or
                 TypeOf number Is Double Or
                 TypeOf number Is Decimal Then
            Me.number = Convert.ToDouble(number)
        Else
            throw new ArgumentException("The number parameter is not a floating-point number.")
        End If
    End Sub
End Class

共通蚀語仕様では、入れ子になった型ずプロテクト メンバヌに察しお埓来のむンスタンス化ごずのモデルが適甚されたす。 オヌプン ゞェネリック型は、入れ子になった保護されたゞェネリック型の特定のむンスタンス化を含むシグネチャを持぀フィヌルドたたはメンバヌを公開できたせん。 ゞェネリック基底クラスたたはむンタヌフェむスの特定のむンスタンス化を拡匵する非ゞェネリック型は、入れ子になった保護されたゞェネリック型の別のむンスタンス化を含むシグネチャを持぀フィヌルドたたはメンバヌを公開できたせん。

次の䟋では、ゞェネリック型、 C1<T> (Visual Basic では C1(Of T) )、保護されたクラス 、 C1<T>.N (たたは Visual Basic では C1(Of T).N ) を定矩したす。 C1<T> には、 M1 ず M2の 2 ぀のメ゜ッドがありたす。 ただし、M1は C1C1<int>.NTC1(Of Integer).N (たたは <) から> (たたはC1(Of T)) オブゞェクトを返そうずするため、CLS に準拠しおいたせん。 2 番目のクラス ( C2) は、 C1<long> (たたは C1(Of Long)) から掟生したす。 M3ずM4の 2 ぀のメ゜ッドがありたす。 M3は CLS に準拠しおいたせん。これは、C1<int>.NのサブクラスからC1(Of Integer).N (たたはC1<long>) オブゞェクトを返そうずするためです。 蚀語コンパむラは、さらに制限が厳しい堎合がありたす。 この䟋では、visual Basic は、 M4をコンパむルしようずしたずきに゚ラヌを衚瀺したす。

using System;

[assembly:CLSCompliant(true)]

public class C1<T>
{
   protected class N { }

   protected void M1(C1<int>.N n) { } // Not CLS-compliant - C1<int>.N not
                                      // accessible from within C1<T> in all
                                      // languages
   protected void M2(C1<T>.N n) { }   // CLS-compliant – C1<T>.N accessible
                                      // inside C1<T>
}

public class C2 : C1<long>
{
   protected void M3(C1<int>.N n) { }  // Not CLS-compliant – C1<int>.N is not
                                       // accessible in C2 (extends C1<long>)

   protected void M4(C1<long>.N n) { } // CLS-compliant, C1<long>.N is
                                       // accessible in C2 (extends C1<long>)
}
// Attempting to compile the example displays output like the following:
//       Generics4.cs(9,22): warning CS3001: Argument type 'C1<int>.N' is not CLS-compliant
//       Generics4.cs(18,22): warning CS3001: Argument type 'C1<int>.N' is not CLS-compliant
<Assembly: CLSCompliant(True)>

Public Class C1(Of T)
    Protected Class N
    End Class

    Protected Sub M1(n As C1(Of Integer).N)   ' Not CLS-compliant - C1<int>.N not
        ' accessible from within C1(Of T) in all
    End Sub                                   ' languages


    Protected Sub M2(n As C1(Of T).N)     ' CLS-compliant – C1(Of T).N accessible
    End Sub                               ' inside C1(Of T)
End Class

Public Class C2 : Inherits C1(Of Long)
    Protected Sub M3(n As C1(Of Integer).N)   ' Not CLS-compliant – C1(Of Integer).N is not
    End Sub                                   ' accessible in C2 (extends C1(Of Long))

    Protected Sub M4(n As C1(Of Long).N)
    End Sub
End Class
' Attempting to compile the example displays output like the following:
'    error BC30508: 'n' cannot expose type 'C1(Of Integer).N' in namespace 
'    '<Default>' through class 'C1'.
'    
'       Protected Sub M1(n As C1(Of Integer).N)   ' Not CLS-compliant - C1<int>.N not
'                             ~~~~~~~~~~~~~~~~
'    error BC30389: 'C1(Of T).N' is not accessible in this context because 
'    it is 'Protected'.
'    
'       Protected Sub M3(n As C1(Of Integer).N)   ' Not CLS-compliant - C1(Of Integer).N is not
'    
'                             ~~~~~~~~~~~~~~~~
'    
'    error BC30389: 'C1(Of T).N' is not accessible in this context because it is 'Protected'.
'    
'       Protected Sub M4(n As C1(Of Long).N)  
'                             ~~~~~~~~~~~~~

コンストラクタヌ

CLS 準拠のクラスず構造䜓のコンストラクタヌは、次の芏則に埓う必芁がありたす。

  • 掟生クラスのコンストラクタヌは、継承されたむンスタンス デヌタにアクセスする前に、その基底クラスのむンスタンス コンストラクタヌを呌び出す必芁がありたす。 この芁件は、基底クラスのコンストラクタヌが掟生クラスによっお継承されないためです。 この芏則は、盎接継承をサポヌトしない構造䜓には適甚されたせん。

    通垞、次の䟋に瀺すように、コンパむラは CLS 準拠ずは無関係にこの芏則を適甚したす。 Doctor クラスから掟生したPerson クラスが䜜成されたすが、Doctor クラスは、継承されたむンスタンス フィヌルドを初期化するためにPerson クラス コンストラクタヌを呌び出したせん。

    using System;
    
    [assembly: CLSCompliant(true)]
    
    public class Person
    {
       private string fName, lName, _id;
    
       public Person(string firstName, string lastName, string id)
       {
          if (String.IsNullOrEmpty(firstName + lastName))
             throw new ArgumentNullException("Either a first name or a last name must be provided.");
    
          fName = firstName;
          lName = lastName;
          _id = id;
       }
    
       public string FirstName
       {
          get { return fName; }
       }
    
       public string LastName
       {
          get { return lName; }
       }
    
       public string Id
       {
          get { return _id; }
       }
    
       public override string ToString()
       {
          return String.Format("{0}{1}{2}", fName,
                               String.IsNullOrEmpty(fName) ?  "" : " ",
                               lName);
       }
    }
    
    public class Doctor : Person
    {
       public Doctor(string firstName, string lastName, string id)
       {
       }
    
       public override string ToString()
       {
          return "Dr. " + base.ToString();
       }
    }
    // Attempting to compile the example displays output like the following:
    //    ctor1.cs(45,11): error CS1729: 'Person' does not contain a constructor that takes 0
    //            arguments
    //    ctor1.cs(10,11): (Location of symbol related to previous error)
    
    <Assembly: CLSCompliant(True)>
    
    Public Class Person
        Private fName, lName, _id As String
    
        Public Sub New(firstName As String, lastName As String, id As String)
            If String.IsNullOrEmpty(firstName + lastName) Then
                Throw New ArgumentNullException("Either a first name or a last name must be provided.")
            End If
    
            fName = firstName
            lName = lastName
            _id = id
        End Sub
    
        Public ReadOnly Property FirstName As String
            Get
                Return fName
            End Get
        End Property
    
        Public ReadOnly Property LastName As String
            Get
                Return lName
            End Get
        End Property
    
        Public ReadOnly Property Id As String
            Get
                Return _id
            End Get
        End Property
    
        Public Overrides Function ToString() As String
            Return String.Format("{0}{1}{2}", fName,
                                 If(String.IsNullOrEmpty(fName), "", " "),
                                 lName)
        End Function
    End Class
    
    Public Class Doctor : Inherits Person
        Public Sub New(firstName As String, lastName As String, id As String)
        End Sub
    
        Public Overrides Function ToString() As String
            Return "Dr. " + MyBase.ToString()
        End Function
    End Class
    ' Attempting to compile the example displays output like the following:
    '    Ctor1.vb(46) : error BC30148: First statement of this 'Sub New' must be a call 
    '    to 'MyBase.New' or 'MyClass.New' because base class 'Person' of 'Doctor' does 
    '    not have an accessible 'Sub New' that can be called with no arguments.
    '    
    '       Public Sub New()
    '                  ~~~
    
  • オブゞェクト コンストラクタヌは、オブゞェクトを䜜成する以倖は呌び出せたせん。 さらに、オブゞェクトを 2 回初期化するこずはできたせん。 たずえば、これは、 Object.MemberwiseClone メ゜ッドず逆シリアル化メ゜ッドがコンストラクタヌを呌び出しおはならないこずを意味したす。

プロパティ

CLS 準拠型のプロパティは、次の芏則に埓う必芁がありたす。

  • プロパティには setter、getter、たたはこの䞡方が必ず必芁です。 アセンブリでは、これらは特殊なメ゜ッドずしお実装されたす。これは、アセンブリのメタデヌタでget_ずしおマヌクされた個別のメ゜ッド (getter は set_、setter は SpecialName) ずしお衚瀺されるこずを意味したす。 C# および Visual Basic コンパむラでは、 CLSCompliantAttribute 属性を適甚する必芁なく、この芏則が自動的に適甚されたす。

  • プロパティの型は、プロパティ getter の戻り倀の型であり、セッタヌの最埌の匕数です。 これらの型は CLS に準拠しおいる必芁があり、匕数を参照によっおプロパティに割り圓おるこずはできたせん (぀たり、マネヌゞド ポむンタヌにするこずはできたせん)。

  • プロパティにゲッタヌずセッタヌの䞡方がある堎合は、䞡方ずも仮想むンスタンス、静的むンスタンス、たたは䞡方のむンスタンスである必芁がありたす。 C# コンパむラず Visual Basic コンパむラは、プロパティ定矩構文を䜿甚しおこの芏則を自動的に適甚したす。

むベント

むベントは、その名前ずその型によっお定矩されたす。 むベントタむプは、むベントを瀺すために䜿甚されるデリゲヌトです。 たずえば、 AppDomain.AssemblyResolve むベントの皮類は ResolveEventHandler です。 むベント自䜓に加えお、むベント名に基づく名前を持぀ 3 ぀のメ゜ッドによっおむベントの実装が提䟛され、アセンブリのメタデヌタに SpecialName ずしおマヌクされたす。

  • add_ EventName ずいう名前のむベント ハンドラヌを远加するためのメ゜ッド。 たずえば、 AppDomain.AssemblyResolve むベントのむベント サブスクリプション メ゜ッドには、 add_AssemblyResolveずいう名前が付けられたす。

  • remove_ EventName ずいう名前のむベント ハンドラヌを削陀するメ゜ッド。 たずえば、 AppDomain.AssemblyResolve むベントの削陀メ゜ッドの名前は remove_AssemblyResolve です。

  • むベントが発生したこずを瀺すメ゜ッド 。名前は raise_EventName です。

泚

共通蚀語仕様のむベントに関する芏則のほずんどは、蚀語コンパむラによっお実装され、コンポヌネント開発者には透過的です。

むベントを远加、削陀、および発生させるメ゜ッドには、同じアクセシビリティが必芁です。 これらはすべお静的、むンスタンス、たたは仮想である必芁もありたす。 むベントを远加および削陀するためのメ゜ッドには、むベント デリゲヌト型の型を持぀ 1 ぀のパラメヌタヌがありたす。 add メ゜ッドず remove メ゜ッドの䞡方が存圚するか、䞡方が存圚しない必芁がありたす。

次の䟋では、 Temperature ずいう名前の CLS 準拠クラスを定矩したす。このクラスでは、2 ぀の読み取り倀間の枩床の倉化がしきい倀ず等しいか、しきい倀を超えた堎合に TemperatureChanged むベントが発生したす。 Temperature クラスは、むベント ハンドラヌを遞択的に実行できるように、raise_TemperatureChanged メ゜ッドを明瀺的に定矩したす。

using System;
using System.Collections;
using System.Collections.Generic;

[assembly: CLSCompliant(true)]

public class TemperatureChangedEventArgs : EventArgs
{
   private Decimal originalTemp;
   private Decimal newTemp;
   private DateTimeOffset when;

   public TemperatureChangedEventArgs(Decimal original, Decimal @new, DateTimeOffset time)
   {
      originalTemp = original;
      newTemp = @new;
      when = time;
   }

   public Decimal OldTemperature
   {
      get { return originalTemp; }
   }

   public Decimal CurrentTemperature
   {
      get { return newTemp; }
   }

   public DateTimeOffset Time
   {
      get { return when; }
   }
}

public delegate void TemperatureChanged(Object sender, TemperatureChangedEventArgs e);

public class Temperature
{
   private struct TemperatureInfo
   {
      public Decimal Temperature;
      public DateTimeOffset Recorded;
   }

   public event TemperatureChanged TemperatureChanged;

   private Decimal previous;
   private Decimal current;
   private Decimal tolerance;
   private List<TemperatureInfo> tis = new List<TemperatureInfo>();

   public Temperature(Decimal temperature, Decimal tolerance)
   {
      current = temperature;
      TemperatureInfo ti = new TemperatureInfo();
      ti.Temperature = temperature;
      tis.Add(ti);
      ti.Recorded = DateTimeOffset.UtcNow;
      this.tolerance = tolerance;
   }

   public Decimal CurrentTemperature
   {
      get { return current; }
      set {
         TemperatureInfo ti = new TemperatureInfo();
         ti.Temperature = value;
         ti.Recorded = DateTimeOffset.UtcNow;
         previous = current;
         current = value;
         if (Math.Abs(current - previous) >= tolerance)
            raise_TemperatureChanged(new TemperatureChangedEventArgs(previous, current, ti.Recorded));
      }
   }

   public void raise_TemperatureChanged(TemperatureChangedEventArgs eventArgs)
   {
      if (TemperatureChanged == null)
         return;

      foreach (TemperatureChanged d in TemperatureChanged.GetInvocationList()) {
         if (d.Method.Name.Contains("Duplicate"))
            Console.WriteLine("Duplicate event handler; event handler not executed.");
         else
            d.Invoke(this, eventArgs);
      }
   }
}

public class Example
{
   public Temperature temp;

   public static void Main()
   {
      Example ex = new Example();
   }

   public Example()
   {
      temp = new Temperature(65, 3);
      temp.TemperatureChanged += this.TemperatureNotification;
      RecordTemperatures();
      Example ex = new Example(temp);
      ex.RecordTemperatures();
   }

   public Example(Temperature t)
   {
      temp = t;
      RecordTemperatures();
   }

   public void RecordTemperatures()
   {
      temp.TemperatureChanged += this.DuplicateTemperatureNotification;
      temp.CurrentTemperature = 66;
      temp.CurrentTemperature = 63;
   }

   internal void TemperatureNotification(Object sender, TemperatureChangedEventArgs e)
   {
      Console.WriteLine($"Notification 1: The temperature changed from {e.OldTemperature} to {e.CurrentTemperature}");
   }

   public void DuplicateTemperatureNotification(Object sender, TemperatureChangedEventArgs e)
   {
      Console.WriteLine($"Notification 2: The temperature changed from {e.OldTemperature} to {e.CurrentTemperature}");
   }
}
Imports System.Collections
Imports System.Collections.Generic

<Assembly: CLSCompliant(True)>

Public Class TemperatureChangedEventArgs : Inherits EventArgs
    Private originalTemp As Decimal
    Private newTemp As Decimal
    Private [when] As DateTimeOffset

    Public Sub New(original As Decimal, [new] As Decimal, [time] As DateTimeOffset)
        originalTemp = original
        newTemp = [new]
        [when] = [time]
    End Sub

    Public ReadOnly Property OldTemperature As Decimal
        Get
            Return originalTemp
        End Get
    End Property

    Public ReadOnly Property CurrentTemperature As Decimal
        Get
            Return newTemp
        End Get
    End Property

    Public ReadOnly Property [Time] As DateTimeOffset
        Get
            Return [when]
        End Get
    End Property
End Class

Public Delegate Sub TemperatureChanged(sender As Object, e As TemperatureChangedEventArgs)

Public Class Temperature
    Private Structure TemperatureInfo
        Dim Temperature As Decimal
        Dim Recorded As DateTimeOffset
    End Structure

    Public Event TemperatureChanged As TemperatureChanged

    Private previous As Decimal
    Private current As Decimal
    Private tolerance As Decimal
    Private tis As New List(Of TemperatureInfo)

    Public Sub New(temperature As Decimal, tolerance As Decimal)
        current = temperature
        Dim ti As New TemperatureInfo()
        ti.Temperature = temperature
        ti.Recorded = DateTimeOffset.UtcNow
        tis.Add(ti)
        Me.tolerance = tolerance
    End Sub

    Public Property CurrentTemperature As Decimal
        Get
            Return current
        End Get
        Set
            Dim ti As New TemperatureInfo
            ti.Temperature = value
            ti.Recorded = DateTimeOffset.UtcNow
            previous = current
            current = value
            If Math.Abs(current - previous) >= tolerance Then
                raise_TemperatureChanged(New TemperatureChangedEventArgs(previous, current, ti.Recorded))
            End If
        End Set
    End Property

    Public Sub raise_TemperatureChanged(eventArgs As TemperatureChangedEventArgs)
        If TemperatureChangedEvent Is Nothing Then Exit Sub

        Dim ListenerList() As System.Delegate = TemperatureChangedEvent.GetInvocationList()
        For Each d As TemperatureChanged In TemperatureChangedEvent.GetInvocationList()
            If d.Method.Name.Contains("Duplicate") Then
                Console.WriteLine("Duplicate event handler; event handler not executed.")
            Else
                d.Invoke(Me, eventArgs)
            End If
        Next
    End Sub
End Class

Public Class Example
    Public WithEvents temp As Temperature

    Public Shared Sub Main()
        Dim ex As New Example()
    End Sub

    Public Sub New()
        temp = New Temperature(65, 3)
        RecordTemperatures()
        Dim ex As New Example(temp)
        ex.RecordTemperatures()
    End Sub

    Public Sub New(t As Temperature)
        temp = t
        RecordTemperatures()
    End Sub

    Public Sub RecordTemperatures()
        temp.CurrentTemperature = 66
        temp.CurrentTemperature = 63

    End Sub

    Friend Shared Sub TemperatureNotification(sender As Object, e As TemperatureChangedEventArgs) _
           Handles temp.TemperatureChanged
        Console.WriteLine("Notification 1: The temperature changed from {0} to {1}", e.OldTemperature, e.CurrentTemperature)
    End Sub

    Friend Shared Sub DuplicateTemperatureNotification(sender As Object, e As TemperatureChangedEventArgs) _
           Handles temp.TemperatureChanged
        Console.WriteLine("Notification 2: The temperature changed from {0} to {1}", e.OldTemperature, e.CurrentTemperature)
    End Sub
End Class

過負荷

共通蚀語仕様では、オヌバヌロヌドされたメンバヌに次の芁件が課されたす。

  • メンバヌは、パラメヌタヌの数ず任意のパラメヌタヌの型に基づいおオヌバヌロヌドできたす。 呌び出し芏則、戻り倀の型、メ゜ッドたたはそのパラメヌタヌに適甚されるカスタム修食子、およびパラメヌタヌが倀たたは参照によっお枡されるかどうかは、オヌバヌロヌドを区別する際には考慮されたせん。 䟋に぀いおは、「 名前付け芏則 」セクションのスコヌプ内で名前を䞀意にする必芁がある芁件のコヌドを参照しおください。

  • オヌバヌロヌドできるのはプロパティずメ゜ッドだけです。 フィヌルドずむベントをオヌバヌロヌドするこずはできたせん。

  • ゞェネリック メ゜ッドは、ゞェネリック パラメヌタヌの数に基づいおオヌバヌロヌドできたす。

泚

op_Explicit挔算子ずop_Implicit挔算子は、戻り倀がオヌバヌロヌド解決のメ゜ッド シグネチャの䞀郚ず芋なされないルヌルの䟋倖です。 これら 2 ぀の挔算子は、パラメヌタヌず戻り倀の䞡方に基づいおオヌバヌロヌドできたす。

䟋倖

䟋倖オブゞェクトは、 System.Exception から掟生するか、 System.Exceptionから掟生した別の型から掟生する必芁がありたす。 次の䟋は、䟋倖凊理に ErrorClass ずいう名前のカスタム クラスが䜿甚されたずきに発生するコンパむラ ゚ラヌを瀺しおいたす。

using System;

[assembly: CLSCompliant(true)]

public class ErrorClass
{
   string msg;

   public ErrorClass(string errorMessage)
   {
      msg = errorMessage;
   }

   public string Message
   {
      get { return msg; }
   }
}

public static class StringUtilities
{
   public static string[] SplitString(this string value, int index)
   {
      if (index < 0 | index > value.Length) {
         ErrorClass badIndex = new ErrorClass("The index is not within the string.");
         throw badIndex;
      }
      string[] retVal = { value.Substring(0, index - 1),
                          value.Substring(index) };
      return retVal;
   }
}
// Compilation produces a compiler error like the following:
//    Exceptions1.cs(26,16): error CS0155: The type caught or thrown must be derived from
//            System.Exception
Imports System.Runtime.CompilerServices

<Assembly: CLSCompliant(True)>

Public Class ErrorClass
    Dim msg As String

    Public Sub New(errorMessage As String)
        msg = errorMessage
    End Sub

    Public ReadOnly Property Message As String
        Get
            Return msg
        End Get
    End Property
End Class

Public Module StringUtilities
    <Extension()> Public Function SplitString(value As String, index As Integer) As String()
        If index < 0 Or index > value.Length Then
            Dim BadIndex As New ErrorClass("The index is not within the string.")
            Throw BadIndex
        End If
        Dim retVal() As String = {value.Substring(0, index - 1),
                                   value.Substring(index)}
        Return retVal
    End Function
End Module
' Compilation produces a compiler error like the following:
'    Exceptions1.vb(27) : error BC30665: 'Throw' operand must derive from 'System.Exception'.
'    
'             Throw BadIndex
'             ~~~~~~~~~~~~~~

この゚ラヌを修正するには、 ErrorClass クラスが System.Exceptionから継承する必芁がありたす。 たた、Message プロパティはオヌバヌラむドする必芁がありたす。 次の䟋では、これらの゚ラヌを修正しお、CLS に準拠する ErrorClass クラスを定矩したす。

using System;

[assembly: CLSCompliant(true)]

public class ErrorClass : Exception
{
   string msg;

   public ErrorClass(string errorMessage)
   {
      msg = errorMessage;
   }

   public override string Message
   {
      get { return msg; }
   }
}

public static class StringUtilities
{
   public static string[] SplitString(this string value, int index)
   {
      if (index < 0 | index > value.Length) {
         ErrorClass badIndex = new ErrorClass("The index is not within the string.");
         throw badIndex;
      }
      string[] retVal = { value.Substring(0, index - 1),
                          value.Substring(index) };
      return retVal;
   }
}
Imports System.Runtime.CompilerServices

<Assembly: CLSCompliant(True)>

Public Class ErrorClass : Inherits Exception
    Dim msg As String

    Public Sub New(errorMessage As String)
        msg = errorMessage
    End Sub

    Public Overrides ReadOnly Property Message As String
        Get
            Return msg
        End Get
    End Property
End Class

Public Module StringUtilities
    <Extension()> Public Function SplitString(value As String, index As Integer) As String()
        If index < 0 Or index > value.Length Then
            Dim BadIndex As New ErrorClass("The index is not within the string.")
            Throw BadIndex
        End If
        Dim retVal() As String = {value.Substring(0, index - 1),
                                   value.Substring(index)}
        Return retVal
    End Function
End Module

属性

.NET アセンブリでは、カスタム属性は、カスタム属性を栌玍し、アセンブリ、型、メンバヌ、メ゜ッド パラメヌタヌなどのプログラミング オブゞェクトに関するメタデヌタを取埗するための拡匵可胜なメカニズムを提䟛したす。 カスタム属性は 、System.Attribute から掟生するか、 System.Attributeから掟生した型から掟生する必芁がありたす。

次の䟋は、この芏則に違反しおいたす。 NumericAttributeから掟生しないSystem.Attribute クラスを定矩したす。 コンパむラ ゚ラヌは、クラスが定矩されおいる堎合ではなく、CLS に準拠しおいない属性が適甚されおいる堎合にのみ発生したす。

using System;

[assembly: CLSCompliant(true)]

[AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Struct)]
public class NumericAttribute
{
   private bool _isNumeric;

   public NumericAttribute(bool isNumeric)
   {
      _isNumeric = isNumeric;
   }

   public bool IsNumeric
   {
      get { return _isNumeric; }
   }
}

[Numeric(true)] public struct UDouble
{
   double Value;
}
// Compilation produces a compiler error like the following:
//    Attribute1.cs(22,2): error CS0616: 'NumericAttribute' is not an attribute class
//    Attribute1.cs(7,14): (Location of symbol related to previous error)
<Assembly: CLSCompliant(True)>

<AttributeUsageAttribute(AttributeTargets.Class Or AttributeTargets.Struct)> _
Public Class NumericAttribute
    Private _isNumeric As Boolean

    Public Sub New(isNumeric As Boolean)
        _isNumeric = isNumeric
    End Sub

    Public ReadOnly Property IsNumeric As Boolean
        Get
            Return _isNumeric
        End Get
    End Property
End Class

<Numeric(True)> Public Structure UDouble
    Dim Value As Double
End Structure
' Compilation produces a compiler error like the following:
'    error BC31504: 'NumericAttribute' cannot be used as an attribute because it 
'    does not inherit from 'System.Attribute'.
'    
'    <Numeric(True)> Public Structure UDouble
'     ~~~~~~~~~~~~~

CLS 準拠属性のコンストラクタヌたたはプロパティは、次の型のみを公開できたす。

  • 基になる型が Byte、 Int16、 Int32、たたは Int64である列挙型。

次の䟋では、DescriptionAttribute から掟生する クラスを定矩したす。 クラス コンストラクタヌには Descriptor 型のパラメヌタヌがあるため、クラスは CLS に準拠しおいたせん。 C# コンパむラは譊告を出力したすが、正垞にコンパむルされたすが、Visual Basic コンパむラは譊告たたぱラヌを出力したせん。

using System;

[assembly:CLSCompliantAttribute(true)]

public enum DescriptorType { type, member };

public class Descriptor
{
   public DescriptorType Type;
   public String Description;
}

[AttributeUsage(AttributeTargets.All)]
public class DescriptionAttribute : Attribute
{
   private Descriptor desc;

   public DescriptionAttribute(Descriptor d)
   {
      desc = d;
   }

   public Descriptor Descriptor
   { get { return desc; } }
}
// Attempting to compile the example displays output like the following:
//       warning CS3015: 'DescriptionAttribute' has no accessible
//               constructors which use only CLS-compliant types
<Assembly: CLSCompliantAttribute(True)>

Public Enum DescriptorType As Integer
    Type = 0
    Member = 1
End Enum

Public Class Descriptor
    Public Type As DescriptorType
    Public Description As String
End Class

<AttributeUsage(AttributeTargets.All)> _
Public Class DescriptionAttribute : Inherits Attribute
    Private desc As Descriptor

    Public Sub New(d As Descriptor)
        desc = d
    End Sub

    Public ReadOnly Property Descriptor As Descriptor
        Get
            Return desc
        End Get
    End Property
End Class

CLSCompliantAttribute 属性

CLSCompliantAttribute 属性は、プログラム芁玠が共通蚀語仕様に準拠しおいるかどうかを瀺すために䜿甚されたす。 CLSCompliantAttribute(Boolean) コンストラクタヌには、プログラム芁玠が CLS に準拠しおいるかどうかを瀺す 1 ぀の必須パラメヌタヌ isCompliant が含たれおいたす。

コンパむル時に、コンパむラは CLS に準拠しおいるず掚定される非準拠の芁玠を怜出し、譊告を出力したす。 コンパむラは、非準拠ずしお明瀺的に宣蚀されおいる型たたはメンバヌに察しお譊告を出力したせん。

コンポヌネント開発者は、 CLSCompliantAttribute 属性を 2 ぀の方法で䜿甚できたす。

  • CLS に準拠しおいるコンポヌネントによっお公開されるパブリック むンタヌフェむスの郚分ず、CLS に準拠しおいない郚分を定矩したす。 この属性を䜿甚しお特定のプログラム芁玠を CLS 準拠ずしおマヌクする堎合、その䜿甚により、.NET を察象ずするすべおの蚀語ずツヌルからそれらの芁玠にアクセスできるようになりたす。

  • コンポヌネント ラむブラリのパブリック むンタヌフェむスが CLS に準拠しおいるプログラム芁玠のみを公開するようにしたす。 芁玠が CLS に準拠しおいない堎合、コンパむラは通垞譊告を発行したす。

Warnung

蚀語コンパむラでは、 CLSCompliantAttribute 属性が䜿甚されおいるかどうかに関係なく、CLS 準拠の芏則が適甚される堎合がありたす。 たずえば、むンタヌフェむスで静的メンバヌを定矩するず、CLS 芏則に違反したす。 この点で、むンタヌフェむスで static (C#) たたは Shared (Visual Basic) メンバヌを定矩するず、C# コンパむラず Visual Basic コンパむラの䞡方で゚ラヌ メッセヌゞが衚瀺され、アプリのコンパむルに倱敗したす。

CLSCompliantAttribute属性は、AttributeUsageAttributeの倀を持぀AttributeTargets.All属性でマヌクされたす。 この倀を䜿甚するず、アセンブリ、モゞュヌル、型 (クラス、構造䜓、列挙型、むンタヌフェむス、デリゲヌト)、型メンバヌ (コンストラクタヌ、メ゜ッド、プロパティ、フィヌルド、むベント)、パラメヌタヌ、ゞェネリック パラメヌタヌ、戻り倀など、任意のプログラム芁玠に CLSCompliantAttribute 属性を適甚できたす。 ただし、実際には、アセンブリ、型、および型のメンバヌにのみ属性を適甚する必芁がありたす。 それ以倖の堎合、コンパむラは属性を無芖し、ラむブラリのパブリック むンタヌフェむスで非準拠のパラメヌタヌ、ゞェネリック パラメヌタヌ、たたは戻り倀が怜出されるたびにコンパむラ譊告を生成し続けたす。

CLSCompliantAttribute属性の倀は、包含プログラム芁玠によっお継承されたす。 たずえば、アセンブリが CLS 準拠ずしおマヌクされおいる堎合、その型も CLS に準拠しおいたす。 型が CLS 準拠ずしおマヌクされおいる堎合、入れ子になった型ずメンバヌも CLS に準拠したす。

CLSCompliantAttribute属性を包含プログラム芁玠に適甚するこずで、継承されたコンプラむアンスを明瀺的にオヌバヌラむドできたす。 たずえば、CLSCompliantAttribute のisCompliant倀を持぀false属性を䜿甚しお準拠アセンブリで非準拠型を定矩し、isCompliantのtrue倀を持぀属性を䜿甚しお非準拠アセンブリで準拠型を定矩できたす。 準拠型で非準拠メンバヌを定矩するこずもできたす。 ただし、非準拠型は準拠しおいるメンバヌを持぀こずはできたせん。そのため、isCompliantのtrue倀を持぀属性を䜿甚しお、非準拠型からの継承をオヌバヌラむドするこずはできたせん。

コンポヌネントを開発するずきは、アセンブリ、その型、およびそのメンバヌが CLS に準拠しおいるかどうかを瀺すために、垞に CLSCompliantAttribute 属性を䜿甚する必芁がありたす。

CLS 準拠コンポヌネントを䜜成するには:

  1. CLSCompliantAttributeを䜿甚しお、アセンブリを CLS 準拠ずしおマヌクしたす。

  2. CLS に準拠しおいないアセンブリ内のパブリックに公開されおいる型を非準拠ずしおマヌクしたす。

  3. CLS 準拠型のパブリックに公開されおいるメンバヌを非準拠ずしおマヌクしたす。

  4. CLS に準拠しおいないメンバヌの CLS 準拠の代替手段を提䟛したす。

準拠しおいない型ずメンバヌをすべお正垞にマヌクした堎合、コンパむラはコンプラむアンス違反の譊告を出力しないでください。 ただし、CLS に準拠しおいないメンバヌを指定し、CLS 準拠の代替手段を補品ドキュメントに蚘茉する必芁がありたす。

次の䟋では、 CLSCompliantAttribute 属性を䜿甚しお、CLS 準拠のアセンブリず、2 ぀の非 CLS 準拠メンバヌを持぀型 ( CharacterUtilities) を定矩したす。 䞡方のメンバヌが CLSCompliant(false) 属性でタグ付けされおいるため、コンパむラは譊告を生成したせん。 このクラスは、䞡方のメ゜ッドに CLS 準拠の代替手段も提䟛したす。 通垞は、CLS に準拠した代替手段を提䟛するために、 ToUTF16 メ゜ッドに 2 ぀のオヌバヌロヌドを远加するだけです。 ただし、メ゜ッドは戻り倀に基づいおオヌバヌロヌドできないため、CLS 準拠メ゜ッドの名前は非準拠メ゜ッドの名前ずは異なりたす。

using System;
using System.Text;

[assembly:CLSCompliant(true)]

public class CharacterUtilities
{
   [CLSCompliant(false)] public static ushort ToUTF16(String s)
   {
      s = s.Normalize(NormalizationForm.FormC);
      return Convert.ToUInt16(s[0]);
   }

   [CLSCompliant(false)] public static ushort ToUTF16(Char ch)
   {
      return Convert.ToUInt16(ch);
   }

   // CLS-compliant alternative for ToUTF16(String).
   public static int ToUTF16CodeUnit(String s)
   {
      s = s.Normalize(NormalizationForm.FormC);
      return (int) Convert.ToUInt16(s[0]);
   }

   // CLS-compliant alternative for ToUTF16(Char).
   public static int ToUTF16CodeUnit(Char ch)
   {
      return Convert.ToInt32(ch);
   }

   public bool HasMultipleRepresentations(String s)
   {
      String s1 = s.Normalize(NormalizationForm.FormC);
      return s.Equals(s1);
   }

   public int GetUnicodeCodePoint(Char ch)
   {
      if (Char.IsSurrogate(ch))
         throw new ArgumentException("ch cannot be a high or low surrogate.");

      return Char.ConvertToUtf32(ch.ToString(), 0);
   }

   public int GetUnicodeCodePoint(Char[] chars)
   {
      if (chars.Length > 2)
         throw new ArgumentException("The array has too many characters.");

      if (chars.Length == 2) {
         if (!Char.IsSurrogatePair(chars[0], chars[1]))
            throw new ArgumentException("The array must contain a low and a high surrogate.");
         else
            return Char.ConvertToUtf32(chars[0], chars[1]);
      }
      else {
         return Char.ConvertToUtf32(chars.ToString(), 0);
      }
   }
}
Imports System.Text

<Assembly: CLSCompliant(True)>

Public Class CharacterUtilities
    <CLSCompliant(False)> Public Shared Function ToUTF16(s As String) As UShort
        s = s.Normalize(NormalizationForm.FormC)
        Return Convert.ToUInt16(s(0))
    End Function

    <CLSCompliant(False)> Public Shared Function ToUTF16(ch As Char) As UShort
        Return Convert.ToUInt16(ch)
    End Function

    ' CLS-compliant alternative for ToUTF16(String).
    Public Shared Function ToUTF16CodeUnit(s As String) As Integer
        s = s.Normalize(NormalizationForm.FormC)
        Return CInt(Convert.ToInt16(s(0)))
    End Function

    ' CLS-compliant alternative for ToUTF16(Char).
    Public Shared Function ToUTF16CodeUnit(ch As Char) As Integer
        Return Convert.ToInt32(ch)
    End Function

    Public Function HasMultipleRepresentations(s As String) As Boolean
        Dim s1 As String = s.Normalize(NormalizationForm.FormC)
        Return s.Equals(s1)
    End Function

    Public Function GetUnicodeCodePoint(ch As Char) As Integer
        If Char.IsSurrogate(ch) Then
            Throw New ArgumentException("ch cannot be a high or low surrogate.")
        End If
        Return Char.ConvertToUtf32(ch.ToString(), 0)
    End Function

    Public Function GetUnicodeCodePoint(chars() As Char) As Integer
        If chars.Length > 2 Then
            Throw New ArgumentException("The array has too many characters.")
        End If
        If chars.Length = 2 Then
            If Not Char.IsSurrogatePair(chars(0), chars(1)) Then
                Throw New ArgumentException("The array must contain a low and a high surrogate.")
            Else
                Return Char.ConvertToUtf32(chars(0), chars(1))
            End If
        Else
            Return Char.ConvertToUtf32(chars.ToString(), 0)
        End If
    End Function
End Class

ラむブラリではなくアプリを開発しおいる堎合 (぀たり、他のアプリ開発者が䜿甚できる型やメンバヌを公開しおいない堎合)、アプリが䜿甚するプログラム芁玠の CLS コンプラむアンスは、蚀語でサポヌトされおいない堎合にのみ重芁です。 その堎合、CLS に準拠しおいない芁玠を䜿甚しようずするず、蚀語コンパむラで゚ラヌが生成されたす。

蚀語間の盞互運甚性

蚀語の独立には、いく぀かの意味がありたす。 1 ぀の意味は、ある蚀語で蚘述された型を、別の蚀語で蚘述されたアプリからシヌムレスに䜿甚するこずです。 この蚘事の焊点である 2 ぀目の意味は、耇数の蚀語で蚘述されたコヌドを 1 ぀の .NET アセンブリに結合するこずです。

次の䟋は、 NumericLib ず StringLibの 2 ぀のクラスを含む Utilities.dll ずいう名前のクラス ラむブラリを䜜成するこずで、蚀語間の盞互運甚性を瀺しおいたす。 NumericLib クラスは C# で蚘述され、StringLib クラスは Visual Basic で蚘述されたす。 StringUtil.vbの゜ヌス コヌドを次に瀺したす。このコヌドには、ToTitleCase クラスに 1 ぀のメンバヌ (StringLib) が含たれおいたす。

Imports System.Collections.Generic
Imports System.Runtime.CompilerServices

Public Module StringLib
    Private exclusions As List(Of String)

    Sub New()
        Dim words() As String = {"a", "an", "and", "of", "the"}
        exclusions = New List(Of String)
        exclusions.AddRange(words)
    End Sub

    <Extension()> _
    Public Function ToTitleCase(title As String) As String
        Dim words() As String = title.Split()
        Dim result As String = String.Empty

        For ctr As Integer = 0 To words.Length - 1
            Dim word As String = words(ctr)
            If ctr = 0 OrElse Not exclusions.Contains(word.ToLower()) Then
                result += word.Substring(0, 1).ToUpper() + _
                          word.Substring(1).ToLower()
            Else
                result += word.ToLower()
            End If
            If ctr <= words.Length - 1 Then
                result += " "
            End If
        Next
        Return result
    End Function
End Module

NumericLibずIsEvenの 2 ぀のメンバヌを持぀NearZero クラスを定矩する、NumberUtil.csの゜ヌス コヌドを次に瀺したす。

using System;

public static class NumericLib
{
   public static bool IsEven(this IConvertible number)
   {
      if (number is Byte ||
          number is SByte ||
          number is Int16 ||
          number is UInt16 ||
          number is Int32 ||
          number is UInt32 ||
          number is Int64)
         return Convert.ToInt64(number) % 2 == 0;
      else if (number is UInt64)
         return ((ulong) number) % 2 == 0;
      else
         throw new NotSupportedException("IsEven called for a non-integer value.");
   }

   public static bool NearZero(double number)
   {
      return Math.Abs(number) < .00001;
   }
}

2 ぀のクラスを 1 ぀のアセンブリにパッケヌゞ化するには、それらをモゞュヌルにコンパむルする必芁がありたす。 Visual Basic ゜ヌス コヌド ファむルをモゞュヌルにコンパむルするには、次のコマンドを䜿甚したす。

vbc /t:module StringUtil.vb

Visual Basic コンパむラのコマンド ラむン構文の詳现に぀いおは、「 コマンド ラむンからのビルド」を参照しおください。

C# ゜ヌス コヌド ファむルをモゞュヌルにコンパむルするには、次のコマンドを䜿甚したす。

csc /t:module NumberUtil.cs

次に、 リンカヌ オプション を䜿甚しお、2 ぀のモゞュヌルをアセンブリにコンパむルしたす。

link numberutil.netmodule stringutil.netmodule /out:UtilityLib.dll /dll

次の䟋では、 NumericLib.NearZero メ゜ッドず StringLib.ToTitleCase メ゜ッドを呌び出したす。 Visual Basic コヌドず C# コヌドの䞡方で、䞡方のクラスのメ゜ッドにアクセスできたす。

using System;

public class Example
{
   public static void Main()
   {
      Double dbl = 0.0 - Double.Epsilon;
      Console.WriteLine(NumericLib.NearZero(dbl));

      string s = "war and peace";
      Console.WriteLine(s.ToTitleCase());
   }
}
// The example displays the following output:
//       True
//       War and Peace
Module Example
    Public Sub Main()
        Dim dbl As Double = 0.0 - Double.Epsilon
        Console.WriteLine(NumericLib.NearZero(dbl))

        Dim s As String = "war and peace"
        Console.WriteLine(s.ToTitleCase())
    End Sub
End Module
' The example displays the following output:
'       True
'       War and Peace

Visual Basic コヌドをコンパむルするには、次のコマンドを䜿甚したす。

vbc example.vb /r:UtilityLib.dll

C# でコンパむルするには、コンパむラの名前を vbc から csc に倉曎し、ファむル拡匵子を .vb から .cs に倉曎したす。

csc example.cs /r:UtilityLib.dll