デリゲートポインターと関数ポインターのエラーと警告を解決する

この記事では、コンパイラの次のエラーと警告について説明します。

  • CS0059: アクセシビリティに一貫性がありません。パラメーター型 'type' はデリゲート 'delegate' よりもアクセスしにくいです。
  • CS0123: デリゲート 'delegate' に一致する 'method' のオーバーロードはありません。
  • CS0148: デリゲート 'delegate' に有効なコンストラクターがありません。
  • CS0410: 'method' のオーバーロードに正しいパラメーターと戻り値の型がありません。
  • CS0644: 'class' は特別なクラス 'class' から派生できません。
  • CS1599: メソッド、デリゲート、または関数ポインターの戻り値の型を 'type' にすることはできません。
  • CS1958: オブジェクトおよびコレクション初期化子の式は、デリゲート作成式に適用できません。
  • CS8755: 'modifier' は、関数ポインター パラメーターの修飾子として使用できません。
  • CS8756: 関数ポインター 'type' は 'count' 引数を受け取りません。
  • CS8757: 'method' のオーバーロードが関数ポインター 'type' と一致しません。
  • CS8758: 'method' と関数ポインター 'type' の間の Ref 不一致。
  • CS8759: 'method' の関数ポインターは静的メソッドではないため作成できません。
  • CS8786: 'convention' の呼び出し規則は、'convention' と互換性がありません。
  • CS8787: メソッド グループを関数ポインターに変換できません。('> がありませんか?)
  • CS8788: '> 演算子のターゲットとして受信側で拡張メソッドを使用できません。
  • CS8789: 固定ステートメントで宣言されたローカルの型を関数ポインター型にすることはできません。
  • CS8806: 'convention' の呼び出し規則は、言語ではサポートされていません。
  • CS8807: 'specifier' は、関数ポインターの有効な呼び出し規則指定子ではありません。
  • CS8808: 'modifier' は有効な関数ポインターの戻り値の型修飾子ではありません。有効な修飾子は 'ref' と 'ref readonly' です。
  • CS8809: 戻り値の型に使用できる 'modifier' 修飾子は 1 つだけです。
  • CS8811: > メソッド グループ 'method' をデリゲート型 'type' に変換できません。
  • CS8909: 関数ポインターを比較すると、同じ関数へのポインターが異なる可能性があるため、予期しない結果になる可能性があります。
  • CS8911: このコンテキストでの関数ポインター型の使用はサポートされていません。

デリゲート署名の不一致

  • CS0059: アクセシビリティに一貫性がありません。パラメーター型 'type' はデリゲート 'delegate' よりもアクセスしにくいです。
  • CS0123: 'method' に対するオーバーロードがデリゲート 'delegate' と一致していません。
  • CS0148: デリゲート 'delegate' に有効なコンストラクターがありません。
  • CS0410: 'method' のオーバーロードに正しいパラメーターと戻り値の型がありません。

デリゲートを作成または割り当てると、コンパイラはターゲット メソッドのシグネチャがデリゲート型の宣言と一致することを確認します。 シグネチャには、パラメーターの型、戻り値の型、およびアクセシビリティが含まれます。 完全な規則については、C# 仕様 のデリゲートアクセシビリティの制約 に関するページを参照してください。

  • デリゲート宣言内のすべてのパラメーター型を、少なくともデリゲート自体と同じくらいアクセス可能な型に変更します (CS0059)。 アセンブリの外部の呼び出し元は引数を指定できないため、 public デリゲートは、そのパラメーター リストでアクセスできない型を参照できません。 詳細については、「 アクセス修飾子」を参照してください。
  • パラメーターの型と戻り値の型が正確に一致するように、メソッド シグネチャまたはデリゲート シグネチャを調整します (CS0123)。 メソッドをデリゲートに割り当てるときに、コンパイラには完全に一致するシグネチャが必要です。
  • デリゲートが準拠コンパイラ (CS0148) によってコンパイルされたことを確認します。 このエラーは、不適切な形式のデリゲート コンストラクターを生成したコンパイラによってビルドされたマネージド アセンブリをインポートするときに発生します。 標準準拠コンパイラを使用してアセンブリを再コンパイルし、エラーを解決します。

Note

CS0410 は、現在の C# コンパイラによって生成されなくなりました。 同じ条件で CS0123 が生成されるようになりました。 以前のコンパイラでコンパイルされた古いアセンブリでも、このエラー コードが参照される可能性があります。

CS0148 はビルドのみの診断です。

Note

この警告は、明示的な ビルド 操作または 再構築 操作中にのみ報告されます。 これは、IntelliSense 診断の一部として IDE での入力中には表示されません。 つまり、フィールドを使用するか削除して警告を修正した場合、プロジェクトをもう一度ビルドまたはリビルドするまで、警告がエラー一覧に保持される可能性があります。

デリゲート型の制限

  • CS0644: 'class' は特別なクラス 'class' から派生できません。
  • CS1599: メソッド、デリゲート、または関数ポインターの戻り値の型を 'type' にすることはできません。
  • CS1958: オブジェクトおよびコレクション初期化子の式は、デリゲート作成式に適用できません。

C# 言語では、 System.Delegateなど、特定の特殊な型を使用する方法が制限されています。 デリゲート宣言の完全な規則については、C# 仕様の デリゲートデリゲート を参照してください。

  • 明示的な基底クラスを削除し、代わりに delegate 宣言を使用します (CS0644)。 クラスは、 System.DelegateSystem.EnumSystem.ValueType、または System.Arrayから明示的に継承することはできません。 コンパイラは、これらの型を暗黙的な基底クラスとして使用します。 たとえば、すべての delegate 宣言は、 System.Delegateから暗黙的に派生します。
  • 戻り値として許可されている型に変更します (CS1599)。 TypedReferenceRuntimeArgumentHandleArgIterator など、.NET クラス ライブラリ内の特定の型は、安全でないスタック操作を有効にする可能性があるため、メソッド、デリゲート、または関数ポインターの戻り値の型として使用できません。
  • デリゲート作成式(CS1958)の後にある波括弧を削除します。 デリゲートには、オブジェクトまたはコレクション初期化子構文を使用して設定できるメンバーがありません。 { }式の後にnew DelegateType(method)がある場合は、ブレースを削除します。

関数ポインターシグネチャの不一致

  • CS8755: 'modifier' は、関数ポインター パラメーターの修飾子として使用できません。
  • CS8756: 関数ポインター 'type' は 'count' 引数を受け取りません。
  • CS8757: 'method' のオーバーロードが関数ポインター 'type' と一致しません。
  • CS8758: 'method' と関数ポインター 'type' の間の Ref 不一致。
  • CS8759: 'method' の関数ポインターは静的メソッドではないため作成できません。
  • CS8787: メソッド グループを関数ポインターに変換できません。('> がありませんか?)
  • CS8788: '> 演算子のターゲットとして受信側で拡張メソッドを使用できません。
  • CS8811: > メソッド グループ 'method' をデリゲート型 'type' に変換できません。

address-of (&) 演算子を使用してメソッドを関数ポインターに割り当てると、コンパイラはメソッドのシグネチャが関数ポインター型と一致することを確認します。 関数ポインターの宣言と使用方法に関する完全な規則については、 関数ポインター安全でないコードに関するセクションを参照してください。

  • サポートされていない修飾子を関数ポインター パラメーター (CS8755) から削除します。 関数ポインター パラメーターは、 refout、および in 修飾子のみをサポートします。 paramsなどの他のパラメーター修飾子は、関数ポインター型宣言では無効です。
  • 関数ポインターのパラメーター数 (CS8756) と一致するように呼び出しサイトの引数の数を変更します。 関数ポインター型は、固定数のパラメーターを定義し、その多くの引数を正確に渡す必要があります。
  • パラメーターの型、戻り値の型、およびパラメーター数が関数ポインター型 (CS8757) と一致するように、メソッドのシグネチャを調整します。 デリゲートとは異なり、関数ポインターは互換性のあるメソッド シグネチャ間の暗黙的な変換をサポートしていません。 一致は正確である必要があります。
  • メソッドのパラメーターと関数ポインター型のパラメーター (ref) の間で、outin、または修飾子を配置します。 各パラメーターの ref の種類は正確に一致する必要があります。 ref パラメーターは、関数ポインター型のinまたはout位置を満たすことはできません。
  • ターゲット メソッドを static (CS8759) に変更します。 関数ポインターは、関連付けられたオブジェクト インスタンスを持たない生の関数アドレスを表すので、静的メソッドのみを指すことができます。
  • 関数ポインター (&) に割り当てるときに、メソッド グループの前に 演算子を追加します。 デリゲートとは異なり、関数ポインターには明示的なアドレス演算子 ( delegate*<void> ptr = &MyMethod;) が必要です。
  • 受信側で拡張メソッドの代わりに静的メソッドを使用します (CS8788)。 &演算子には、ダイレクト メソッド参照が必要です。 インスタンスで呼び出される拡張メソッドには、関数ポインターでキャプチャできない暗黙的なレシーバーがあります。
  • &演算子を削除し、代わりにデリゲート構文を使用するか、デリゲートから関数ポインター (CS8811) にターゲットの型を変更します。 &演算子は、デリゲートではなく関数ポインターを生成します。 メソッド グループをデリゲート型に割り当てるには、 & を省略し、標準のデリゲート作成構文を使用します。

関数ポインター呼び出し規則と戻り値の型

  • CS8786: 'convention' の呼び出し規則は、'convention' と互換性がありません。
  • CS8806: 'convention' の呼び出し規則は、言語ではサポートされていません。
  • CS8807: 'specifier' は、関数ポインターの有効な呼び出し規則指定子ではありません。
  • CS8808: 'modifier' は有効な関数ポインターの戻り値の型修飾子ではありません。有効な修飾子は 'ref' と 'ref readonly' です。
  • CS8809: 戻り値の型に使用できる 'modifier' 修飾子は 1 つだけです。

関数ポインター宣言には、呼び出し規則と省略可能な戻り値の型修飾子が含まれます。 コンパイラはこれらのオプションを検証します。 完全なルールについては、「 関数ポインター」を参照してください。

  • メソッドの呼び出し規則または関数ポインター型の呼び出し規則を一致するように変更します (CS8786)。 メソッドを関数ポインターに割り当てるときは、呼び出し規則に互換性がある必要があります。 たとえば、 Cdecl を使用するメソッドは、 Stdcall で宣言された関数ポインターに割り当てることはできません。
  • 関数ポインター宣言 (CS8806) でサポートされている呼び出し規則を使用します。 この言語では、 managedunmanagedがサポートされます。 特定のアンマネージ規則の場合は、角かっこで囲まれた規則としてunmanagedunmanaged[Cdecl]unmanaged[Stdcall]unmanaged[Thiscall]、またはunmanaged[Fastcall] キーワードを使用します。
  • 無効な指定子を、サポートされている呼び出し規則 (CS8807) に置き換えます。 managedunmanaged、またはunmanagedを使用し、呼び出し規約の種類を角かっこ (unmanaged[Cdecl] など) で指定します。
  • 戻り値の型修飾子として ref または ref readonly のみを使用します (CS8808)。 outinなどの他の修飾子は、関数ポインターの戻り値の型には無効です。
  • 重複する戻り値の型修飾子を削除して、1 つの ref または ref readonly のみが表示されるようにします (CS8809)。 コンパイラは、関数ポインター宣言で最大 1 つの戻り値の型修飾子を使用できます。

関数ポインターの使用制限

  • CS8789: 固定ステートメントで宣言されたローカルの型を関数ポインター型にすることはできません。
  • CS8909: 関数ポインターを比較すると、同じ関数へのポインターが異なる可能性があるため、予期しない結果になる可能性があります。
  • CS8911: このコンテキストでの関数ポインター型の使用はサポートされていません。

コンパイラは、特定のコンテキストで関数ポインター型を使用する方法を制限します。 完全なルールについては、「 関数ポインター」を参照してください。

  • fixed ステートメントのローカル変数型を、関数ポインター型 (CS8789) ではなくデータ ポインター型に変更します。 fixed ステートメントは、データ アクセスのためにマネージド オブジェクトをメモリにピン留めします。 関数ポインターは、データではなくコード アドレスを表し、ピン留めすることはできません。
  • 関数ポインターの等価性の比較は避けてください (CS8909)。 この警告は、関数ポインターを == または != と比較すると、予期しない結果が発生する可能性があることを示します。 サンク処理や JIT コンパイルなどの実装の詳細により、ランタイムが同じ関数に対して異なるポインターを返す場合があります。 比較が意図的であることを確認するときに警告を抑制するには、 #pragma warning disable CS8909を使用します。
  • 関数ポインターの使用法をサポートされているコンテキスト (CS8911) に移動します。 関数ポインター型は、属性引数や typeof 式など、特定の位置では使用できません。 サポートされていないコンテキストで関数ポインター型を使用しないようにコードを再構築します。