System.Runtime.Versioning.ComponentGuaranteesAttribute クラス

この記事では、この API のリファレンス ドキュメントへの補足的な解説を提供します。

コンポーネント ComponentGuaranteesAttribute およびクラス ライブラリの開発者は、ライブラリのコンシューマーが複数のバージョンにわたって期待できる互換性のレベルを示すために使用されます。 これは、ライブラリまたはコンポーネントの将来のバージョンが既存のクライアントを中断しないことを保証するレベルを示します。 クライアントは、バージョン間の ComponentGuaranteesAttribute 安定性を確保するために、独自のインターフェイスを設計する際の補助として使用できます。

Note

共通言語ランタイム (CLR) では、この属性は使用されません。 その値は、コンポーネント作成者の意図を正式に文書化することです。 コンパイル時ツールでは、これらの宣言を使用して、宣言された保証を損なうコンパイル時エラーを検出することもできます。

互換性のレベル

ComponentGuaranteesAttribute のレベルの互換性がサポートされています。この互換性は、列挙型の ComponentGuaranteesOptions メンバーによって表されます。

  • バージョン間の互換性はありません (ComponentGuaranteesOptions.None)。 クライアントは、将来のバージョンが既存のクライアントを中断することを期待できます。 詳細については、この記事の後半の 「互換性 なし」セクションを参照してください。

  • Side-by-side version-to-version compatibility (ComponentGuaranteesOptions.SideBySide). コンポーネントは、同じアプリケーションに複数のバージョンのアセンブリが読み込まれるときに動作するようにテストされていますメイン。 一般に、将来のバージョンは互換性を損なう可能性があります。 ただし、破壊的変更が行われると、古いバージョンは変更されませんが、新しいバージョンと共に存在します。 サイド バイ サイド実行は、重大な変更が行われたときに既存のクライアントを動作させる方法です。 詳細については、この記事で後述する サイド バイ サイド互換性 のセクションを参照してください。

  • 安定したバージョン間の互換性 (ComponentGuaranteesOptions.Stable)。 今後のバージョンではクライアントを中断する必要はありません。また、サイド バイ サイドの実行は必要ありません。 ただし、クライアントが誤って破損した場合は、サイド バイ サイド実行を使用して問題を解決できる可能性があります。 詳細については、「安定した互換性」セクションを参照してください。

  • Exchange のバージョン間の互換性 (ComponentGuaranteesOptions.Exchange)。 将来のバージョンがクライアントを壊さないよう、特別な注意が払われます。 クライアントは、相互に独立して展開されている他のアセンブリとの通信に使用されるインターフェイスのシグネチャで、これらの型のみを使用する必要があります。 特定のアプリケーションに含まれるのは、これらの型の 1 つのバージョンのみですメインこれは、クライアントが中断した場合、サイド バイ サイド実行では互換性の問題を解決できないことを意味します。 詳細については、「Exchange の種類の互換性」セクションを参照してください。

以降のセクションでは、各レベルの保証について詳しく説明します。

互換性なし

コンポーネントをマーク ComponentGuaranteesOptions.None すると、プロバイダーは互換性に関する保証を行いません。 クライアントは、公開されているインターフェイスに依存しないようにする必要があります。 このレベルの互換性は、試験的な型、または一般に公開されているが、常に同時に更新されるコンポーネントのみを対象とする型に役立ちます。 None は、このコンポーネントを外部コンポーネントで使用しないことを明示的に示します。

Side-by-side 互換性

コンポーネントをマークComponentGuaranteesOptions.SideBySideすると、複数のバージョンのアセンブリが同じアプリケーションに読み込まれるときに、コンポーネントが動作するようにテストされたことを示しますメイン。 重大な変更は、バージョン番号が大きいアセンブリに対して行われる限り許可されます。 アセンブリの古いバージョンにバインドされているコンポーネントは、引き続き古いバージョンにバインドすることが想定されており、他のコンポーネントは新しいバージョンにバインドできます。 以前のバージョンを破壊的に変更することによって宣言されている SideBySide コンポーネントを更新することもできます。

安定した互換性

型をマークComponentGuaranteesOptions.Stableすると、型がバージョン間でメイン安定していることが示されます。 ただし、安定した型の side-by-side バージョンが同じアプリケーションに存在する場合もありますメイン。

安定した型メインバイナリ互換性バーが高くなります。 このため、プロバイダーは安定した型に重大な変更を加えないようにする必要があります。 次の種類の変更が可能です。

  • プライベート インスタンス フィールドを型に追加したり、型からフィールドを削除したりする場合は、シリアル化の形式が損なわれません。
  • シリアル化できない型をシリアル化可能な型に変更する。 (ただし、シリアル化可能な型をシリアル化できない型に変更することはできません)。
  • メソッドからより派生した新しい例外をスローする。
  • メソッドのパフォーマンスの向上。
  • 変更が大部分のクライアントに悪影響を及ぼさない限り、戻り値の範囲を変更します。
  • ビジネス上の正当な理由が高く、悪影響を受けるクライアントの数が少ない場合に、重大なバグを修正します。

安定したコンポーネントの新しいバージョンは既存のクライアントを中断することは想定されていないため、一般に、アプリケーションで必要な安定したコンポーネントのバージョンは 1 つだけですメイン。 ただし、安定した型は、すべてのコンポーネントが同意する既知の交換の種類として使用されないため、これは要件ではありません。 したがって、安定したコンポーネントの新しいバージョンが誤ってコンポーネントを中断し、他のコンポーネントに新しいバージョンが必要な場合は、古いコンポーネントと新しいコンポーネントの両方を読み込むことで問題を解決できる可能性があります。

Stable より強力なバージョン互換性保証 Noneを提供します。 これは、複数バージョンのコンポーネントの一般的な既定値です。

Stableと組み合わせることができますSideBySide。これは、コンポーネントが互換性を損なわないが、特定のアプリケーションに複数のバージョンが読み込まれるときに動作するようにテストされることを示しますメイン。

型またはメソッドのマークが付 Stableいた後は、次のように Exchangeアップグレードできます。 ただし、〘に Noneダウングレードすることはできません。

Exchange の種類の互換性

型をマーク ComponentGuaranteesOptions.Exchange すると、バージョン互換性が保証されるよりも Stable強力になり、すべての型の中で最も安定したものに適用する必要があります。 これらの型は、すべてのコンポーネント境界 (CLR の任意のバージョンまたはコンポーネントまたはアプリケーションの任意のバージョン) と空間 (クロスプロセス、1 つのプロセスでの CLR 間、アプリケーション間の実行)、1 つの CLR でのクロスアプリケーション実行メインの両方で、独立して構築されたコンポーネント間の交換に使用することを目的としています。 交換の種類に重大な変更が加えられた場合、型の複数のバージョンを読み込んで問題を解決することはできません。

Exchange の種類は、問題が非常に深刻な場合 (重大なセキュリティの問題など) または破損の確率が非常に低い場合 (つまり、コードが依存関係を取ることができなかったランダムな方法で動作が既に壊れている場合) にのみ変更する必要があります。 交換の種類に対して次の種類の変更を行うことができます。

  • 新しいインターフェイス定義の継承を追加します。

  • 新しく継承されたインターフェイス定義のメソッドを実装する新しいプライベート メソッドを追加します。

  • 新しい静的フィールドを追加します。

  • 新しい静的メソッドを追加します。

  • 新しい非仮想インスタンス メソッドを追加します。

以下は破壊的変更と見なされ、プリミティブ型では使用できません。

  • シリアル化形式の変更。 バージョン トレラントなシリアル化が必要です。

  • プライベート インスタンス フィールドの追加または削除。 これにより、型のシリアル化形式が変更され、リフレクションを使用するクライアント コードが破損するリスクがあります。

  • 型のシリアル化可能性の変更。 シリアル化できない型はシリアル化できない場合があります。逆も可能です。

  • メソッドから異なる例外をスローする。

  • メンバー定義がこの可能性を引き出し、クライアントが不明な値を処理する方法を明確に示す場合を除き、メソッドの戻り値の範囲を変更します。

  • ほとんどのバグを修正します。 型のコンシューマーは、既存の動作に依存します。

コンポーネント、型、またはメンバーが保証でExchangeマークされた後は、いずれかまたは None.Stable

通常、交換型は基本型 (.NET などInt32) とString、パブリック インターフェイスで一般的に使用されるインターフェイス (.IComparable<T>IEnumerable<T>NET などIList<T>) です。

交換の種類がでもマークされている他の種類のみをパブリックに公開Exchange互換性。 さらに、交換の種類が変更される可能性がある Windows API の動作に依存できません。

コンポーネントの保証

次の表は、コンポーネントの特性と使用方法が互換性の保証にどのように影響するかを示しています。

コンポーネントの特性 Exchange 安定 Side-by-Side なし
個別にバージョン管理するコンポーネント間のインターフェイスで使用できます。 N N N
個別にバージョン管理するアセンブリで (プライベートに) 使用できます。 N
1 つのアプリケーションに複数のバージョンを含めることができますメイン。 N Y Y
破壊的変更を加えることができます N N Y Y
アセンブリの特定の複数のバージョンを一緒に読み込むことができるようにテストします。 N N N
破壊的変更を行うことができます。 N N N
非常に安全な非破壊的サービスの変更を行うことができます。 Y

属性を適用する

アセンブリ、型、または型メンバーに適用 ComponentGuaranteesAttribute できます。 そのアプリケーションは階層構造になっています。 つまり、既定では、アセンブリ レベルで属性のプロパティによって定義される Guarantees 保証によって、アセンブリ内のすべての型とそれらの型のすべてのメンバーの保証が定義されます。 同様に、保証が型に適用される場合、既定では、型の各メンバーにも適用されます。

この継承された保証は、個々の型と型の ComponentGuaranteesAttribute メンバーに適用することでオーバーライドできます。 ただし、既定値をオーバーライドする保証は、保証を弱めることもできます。彼らはそれを強化することはできません。 たとえば、アセンブリが保証で None マークされている場合、その型とメンバーは互換性の保証を受けず、アセンブリ内の型またはメンバーに適用されるその他の保証は無視されます。

保証をテストする

このプロパティは Guarantees 、属性でマークされた列挙体の ComponentGuaranteesOptions メンバーを FlagsAttribute 返します。 これは、不明な可能性があるフラグをマスクして、関心のあるフラグをテストする必要があることを意味します。 たとえば、次の例では、型が Stable.

// Test whether guarantee is Stable.
if ((guarantee & ComponentGuaranteesOptions.Stable) == ComponentGuaranteesOptions.Stable)
   Console.WriteLine("{0} is marked as {1}.", typ.Name, guarantee);
' Test whether guarantee is Stable.
If (guarantee And ComponentGuaranteesOptions.Stable) = ComponentGuaranteesOptions.Stable Then
   Console.WriteLine("{0} is marked as {1}.", typ.Name, guarantee)
End If

次の例では、型がマーク Stable されているかどうかをテストします Exchange

// Test whether guarantee is Stable or Exchange.
if ((guarantee & (ComponentGuaranteesOptions.Stable | ComponentGuaranteesOptions.Exchange)) > 0)
   Console.WriteLine("{0} is marked as Stable or Exchange.", typ.Name, guarantee);
' Test whether guarantee is Stable or Exchange.
If (guarantee And (ComponentGuaranteesOptions.Stable Or ComponentGuaranteesOptions.Exchange)) > 0 Then
   Console.WriteLine("{0} is marked as Stable or Exchange.", typ.Name, guarantee)
End If

次の例では、型が (つまり、どちらでもない) とNoneマークされていることをテストしますExchangeStable

// Test whether there is no guarantee (neither Stable nor Exchange).
if ((guarantee & (ComponentGuaranteesOptions.Stable | ComponentGuaranteesOptions.Exchange)) == 0)
   Console.WriteLine("{0} has no compatibility guarantee.", typ.Name, guarantee);
' Test whether there is no guarantee (neither Stable nor Exchange).
If (guarantee And (ComponentGuaranteesOptions.Stable Or ComponentGuaranteesOptions.Exchange)) = 0 Then
   Console.WriteLine("{0} has no compatibility guarantee.", typ.Name, guarantee)
End If