次の方法で共有


ジェネリック型パラメーターとジェネリック型引数に関連するエラーと警告を解決する

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

  • CS0080: 非ジェネリック宣言では制約を使用できません。
  • CS0081: 型パラメーター宣言は、型ではなく識別子である必要があります。
  • CS0224: vararg を持つメソッドは、ジェネリックにすることも、ジェネリック型にすることも、params パラメーターを持つことはできません。
  • CS0304: new() 制約がないため、変数型 'type' のインスタンスを作成できません。
  • CS0305: ジェネリック型 'ジェネリック型' を使用するには、'number' 型引数が必要です。
  • CS0306: 型 'type' は型引数として使用できません。
  • CS0307: 'construct' 'identifier' はジェネリック メソッドではありません。式リストを使用する場合は、 < 式をかっこで囲みます。
  • CS0308: 非ジェネリック型またはメソッド 'identifier' は型引数と共に使用できません。
  • CS0310: ジェネリック型またはメソッド 'generic' でパラメーター 'parameter' として使用するには、型 'typename' は、パブリック パラメーターなしのコンストラクターを持つ非抽象型である必要があります。
  • CS0311: 型 'type1' は、ジェネリック型またはメソッド '<name>' の型パラメーター 'T' として使用できません。'type1' から 'type2' への暗黙的な参照変換はありません。
  • CS0312: 型 'type1' は、ジェネリック型またはメソッド 'name' の型パラメーター 'name' として使用できません。null 許容型 'type1' が 'type2' の制約を満たしていません。
  • CS0313: 型 'type1' は、ジェネリック型またはメソッド 'type2' の型パラメーター 'parameter name' として使用できません。null 許容型 'type1' が 'type2' の制約を満たしていません。Null 許容型は、どのインターフェイス制約も満たできません。
  • CS0314: 型 'type1' は、ジェネリック型またはメソッド 'name' の型パラメーター 'name' として使用できません。'type1' から 'type2' へのボックス化変換または型パラメーター変換はありません。
  • CS0315: 型 'valueType' は、ジェネリック型またはメソッド 'TypeorMethod<T>' の型パラメーター 'T' として使用できません。'valueType' から 'referenceType' へのボックス化変換はありません。
  • CS0403: null 非許容値型である可能性があるため、null を型パラメーター 'name' に変換できません。代わりに 'default('T')' を使用することを検討してください。
  • CS0412: 'parameter': パラメーター、ローカル変数、またはローカル関数は、メソッド型パラメーターと同じ名前を持つことはできません。
  • CS0413: 型パラメーター 'type parameter' は、クラス型制約も 'class' 制約も持たないため、'as' 演算子と共に使用できません。
  • CS0417: 'identifier': 変数型のインスタンスを作成するときに引数を指定できません。
  • CS0694: 型パラメーター 'identifier' の名前は、含まれている型またはメソッドと同じです。
  • CS0695: 'type' は'interface1' と 'interface2' の両方を実装できません。これは、一部の型パラメーターの置換で統一される可能性があるためです。
  • CS0698: ジェネリック型は属性クラスであるため、'type' から派生することはできません。
  • CS9338: アクセシビリティに一貫性がありません。型 'type1' はクラス 'type2' よりもアクセスしにくいです。

型パラメーターの宣言と名前付け

次のエラーは、ジェネリック型とメソッドで型パラメーターを宣言し、名前を付ける方法に関連しています。

  • CS0080: 非ジェネリック宣言では制約を使用できません。
  • CS0081: 型パラメーター宣言は、型ではなく識別子である必要があります。
  • CS0412: 'parameter': パラメーター、ローカル変数、またはローカル関数は、メソッド型パラメーターと同じ名前を持つことはできません。
  • CS0694: 型パラメーター 'identifier' の名前は、含まれている型またはメソッドと同じです。

これらのエラーを修正するには、型パラメーターが有効な識別子で宣言されていること、制約句がジェネリック宣言にのみ適用されていること、および型パラメーター名がスコープ内の他の識別子と競合しないようにします。

  • 非ジェネリック宣言 (CS0080) から制約句を削除します。 where句は、型パラメーターを宣言するジェネリック型とメソッドでのみ使用できます。制約では、型引数が満たす必要がある要件が定義されているためです。 制約を適用する必要がある場合は、最初に型またはメソッドの宣言に型パラメーターを追加します。 たとえば、public class MyClass where MyClass : System.IDisposablepublic class MyClass<T> where T : System.IDisposable に変更します。
  • 実際の型名を型パラメーター宣言の識別子に置き換えます (CS0081)。 型パラメーターの目的は、ジェネリック型またはメソッドを使用するときに実際の型に置き換えられるプレースホルダーとして機能するため、具象型 (TTKeyなど) ではなく、識別子 (TValueint、またはstringなど) を使用して宣言する必要があります。 たとえば、public void F<int>()public void F<T>() に変更します。
  • 名前の競合を回避するために、型パラメーター、ローカル変数、またはパラメーターの名前を変更します (CS0412CS0694)。 型パラメーター名は、同じスコープ内の識別子をシャドウできません。 含まれている型またはメソッドの名前と一致することはできません。 このような競合により、どの識別子が参照されているかがあいまいになります。 たとえば、メソッド public void F<T>()がある場合は、そのメソッド内でローカル変数 double T 宣言することはできません。また、その包含型 (class C<C>) と同じ型パラメーターに名前を付けることはできません。

詳細については、「ジェネリック型パラメーターとジェネリックを参照してください。

型引数の数と使用法

次のエラーは、ジェネリック型とメソッドに正しい型引数の数と型を指定することに関連しています。

  • CS0224: vararg を持つメソッドは、ジェネリックにすることも、ジェネリック型にすることも、params パラメーターを持つことはできません。
  • CS0305: ジェネリック型 'ジェネリック型' を使用するには、'number' 型引数が必要です。
  • CS0306: 型 'type' は型引数として使用できません。
  • CS0307: 'construct' 'identifier' はジェネリック メソッドではありません。式リストを使用する場合は、 < 式の周りにかっこを使用します。
  • CS0308: 非ジェネリック型またはメソッド 'identifier' は型引数と共に使用できません。

これらのエラーを修正するには、ジェネリック宣言で必要な型引数の正確な数を指定してください。 型引数として有効な型のみを使用します。 非ジェネリック コンストラクトには型引数を適用しないでください。

  • __arglist (CS0224) を使用するメソッドからジェネリック型パラメーターを削除するか、ジェネリック型宣言を含めます。 __arglist キーワードはジェネリックと互換性がありません。これは、可変引数リストを処理するためのランタイム メカニズムが、ジェネリック型パラメーターに必要な型置換と競合するためです。 この制限は、ジェネリック型内のジェネリック メソッドまたはメソッドと組み合わせて使用する場合、 params キーワードにも適用されます。
  • ジェネリック型またはメソッド宣言 (CS0305) で指定された型引数の正確な数を指定します。 ジェネリック型がインスタンス化されるときに、定義で宣言された各ジェネリック型パラメーターには、対応する型引数が必要です。 コンパイラは、型パラメーターごとに置き換える具象型を認識する必要があります。 たとえば、クラスがclass MyList<T>として宣言されている場合は、MyList<int>ではなく、MyList<int, string>など、クラスを使用するときに 1 つの型引数を指定する必要があります。
  • 型引数として有効な型のみを使用します (CS0306)。 ジェネリック型にはガベージ コレクターが追跡できるマネージド型が必要であり、ポインター型はアンマネージであるため、 int*char*などのポインター型は型引数として使用できません。 ジェネリック コンテキストでポインターを操作する必要がある場合は、ジェネリックと安全でないコードの混在を避けるために、 IntPtr の使用を検討するか、コードを再構築することを検討してください。
  • 非ジェネリック コンストラクト (CS0307、CS0308) から型引数構文を削除します。 山かっこで囲まれた型引数 ( <int> など) は、型パラメーターを宣言するジェネリック型とメソッドにのみ適用できます。 型引数を完全に削除するか、型のジェネリック バージョンを含む名前空間をインポートする必要があります。 たとえば、 IEnumerator<T> では using System.Collections.Generic; ディレクティブが必要ですが、 IEnumeratorSystem.Collections内にあります。

詳細については、「ジェネリック型パラメーターとジェネリックを参照してください。

コンストラクターの制約

次のエラーは、ジェネリック型パラメーターの new() 制約に関連しています。

  • CS0304: new() 制約がないため、変数型 'type' のインスタンスを作成できません。
  • CS0310: ジェネリック型またはメソッド 'generic' でパラメーター 'parameter' として使用するには、型 'typename' は、パブリック パラメーターなしのコンストラクターを持つ非抽象型である必要があります。
  • CS0417: 'identifier': 変数型のインスタンスを作成するときに引数を指定できません。

これらのエラーを修正するには、インスタンス化する必要がある型パラメーターに new() 制約を追加し、型引数にパブリック パラメーターなしのコンストラクターがあることを確認し、型パラメーターのインスタンスを構築するときに引数を渡さないようにします。

  • new()制約を型パラメーター宣言 (CS0304) に追加します。 new演算子を使用してジェネリック型またはメソッド内に型パラメーターのインスタンスを作成する場合、コンパイラは、実行時に指定された型引数にパラメーターなしのコンストラクターがあることを保証できる必要があります。 new()制約は、コンパイル時にこの保証を提供し、コンパイラが適切なインスタンス化コードを生成できるようにします。 たとえば、メンバー class C<T>T t = new T();がある場合は、宣言を class C<T> where T : new() に変更する必要があります。
  • 制約付き型パラメーターで使用される型引数 new() パブリック パラメーターなしのコンストラクター (CS0310) があることを確認します。 ジェネリック型またはメソッドが型パラメーターに対して new() 制約を宣言する場合、型引数として使用される具象型は非抽象型であり、パブリック パラメーターなしのコンストラクターを提供する必要があります。 型に非パブリック コンストラクター ( privateprotectedなど) のみが含まれている場合、またはパラメーターを持つコンストラクターしかない場合は、 new() 制約を満たすことはできません。 このエラーを修正するには、パブリック パラメーターなしのコンストラクターを型に追加するか、既に存在する別の型引数を使用します。
  • 型パラメーターをインスタンス化するときにコンストラクターの引数を削除します (CS0417)。 new()制約ではパラメーターなしのコンストラクターの存在のみが保証されるため、new T(arguments)に引数を渡そうとすることは許可されません。コンパイラは、これらの特定のパラメーター型を持つコンストラクターが、Tに置き換わる型に存在することを確認できないためです。 特定の引数を持つインスタンスを構築する必要がある場合は、ファクトリ メソッド、抽象ファクトリ パターン、または必要な構築動作を定義する特定の基底クラス/インターフェイス制約の使用を検討してください。

詳細については、 型パラメーターの制約new() 制約を参照してください。

制約充足と変換

次のエラーは、ジェネリック型パラメーターの制約を満たしていない型引数に関連しています。

  • CS0311: 型 'type1' は、ジェネリック型またはメソッド '<name>' の型パラメーター 'T' として使用できません。'type1' から 'type2' への暗黙的な参照変換はありません。
  • CS0312: 型 'type1' は、ジェネリック型またはメソッド 'name' の型パラメーター 'name' として使用できません。null 許容型 'type1' は 'type2' の制約を満たしません。
  • CS0313: 型 'type1' は、ジェネリック型またはメソッド 'type2' の型パラメーター 'parameter name' として使用できません。null 許容型 'type1' が 'type2' の制約を満たしていません。Null 許容型は、どのインターフェイス制約も満たできません。
  • CS0314: 型 'type1' は、ジェネリック型またはメソッド 'name' の型パラメーター 'name' として使用できません。'type1' から 'type2' へのボックス化変換または型パラメーター変換はありません。
  • CS0315: 型 'valueType' は、ジェネリック型またはメソッド 'TypeorMethod<T>' の型パラメーター 'T' として使用できません。'valueType' から 'referenceType' へのボックス化変換はありません。

これらのエラーを修正するには、適切な変換によってすべての制約を満たす型引数を使用し、派生クラスが基底クラスの制約を繰り返すようにし、null 許容値型に特別な制約要件があることを理解します。

  • 型引数を、制約型 (CS0311) への暗黙的な参照変換を持つ引数に変更します。 型パラメーターに where T : BaseType のような制約がある場合、暗黙的な参照変換または ID 変換によって、任意の型引数を BaseType に変換できる必要があります。 型引数は、それ自体 BaseType するか、 BaseTypeから派生するか、インターフェイスの場合は BaseType を実装する必要があります。 暗黙的な数値変換 ( short から int など) は、ジェネリック型パラメーターの制約を満たしていません。これらの変換は、参照変換ではなく値変換であるためです。
  • 派生クラス宣言 (CS0314) で基底クラスの型パラメーター制約を繰り返します。 派生ジェネリック クラスが、型パラメーターに制約がある基本ジェネリック クラスから継承する場合、派生クラスは対応する型パラメーターに対して同じ制約を宣言する必要があります。 派生クラスに指定された型引数が基底クラスの要件を満たしていることをコンパイラが確認する必要があるため、繰り返しが必要です。 たとえば、 public class A<T> where T : SomeClassがある場合は、そこから派生するすべてのクラスを public class B<T> : A<T> where T : SomeClassとして宣言する必要があります。
  • null 非許容値型を使用するか、制約の型 (CS0312CS0313) を変更します。 null 許容値型 ( int? など) は、基になる値型とは異なり、同じ制約を満たしていません。 int?intの間に暗黙的な変換はありません。また、null 許容値型は、その基になる値型がインターフェイスを実装していても、null 許容ラッパー自体がインターフェイスを実装していないため、インターフェイスの制約を満たすことはできません。 これらのエラーを修正するには、値型の null 非許容形式を型引数として使用するか、必要に応じて、 object または null 許容参照型を受け入れるように制約を調整します。
  • 型引数が参照型またはクラス制約 (CS0315) を満たしていることを確認します。 型パラメーターがクラス型 ( where T : SomeClass など) に制約されている場合、制約リレーションシップを満たすボックス化変換がないため、型引数として値型 (構造体) を使用することはできません。 制約には、制約型との継承または実装リレーションシップを持つ参照型が必要です。 このエラーを解決するには、意味的に適切な場合は構造体をクラスに変更するか、ジェネリック型が値型で動作できる場合はクラス制約を削除します。

詳細については、「 型パラメーターの制約 」および 「暗黙的な変換」を参照してください。

ジェネリック型の利用制約

次のエラーは、ジェネリック型の使用方法に関する制限に関連しています。

  • CS0403: null 非許容値型である可能性があるため、null を型パラメーター 'name' に変換できません。代わりに 'default('T')' を使用することを検討してください。
  • CS0413: 型パラメーター 'type parameter' は、クラス型制約も 'class' 制約も持たないため、'as' 演算子と共に使用できません。
  • CS0695: 'type' は'interface1' と 'interface2' の両方を実装できません。これは、一部の型パラメーターの置換で統一される可能性があるためです。
  • CS0698: ジェネリック型は属性クラスであるため、'type' から派生することはできません。
  • CS9338: アクセシビリティに一貫性がありません。型 'type1' はクラス 'type2' よりもアクセスしにくいです。

これらのエラーを修正するには、制約のない型パラメーターのdefaultではなくnullを使用し、as演算子を使用するときにクラス制約を追加し、インターフェイスの統一の競合を回避し、ジェネリック属性クラスを作成せず、型引数が含まれるメンバーの可視性と一致することを確認します。

  • null割り当てをdefault(T)に置き換えるか、クラス制約を追加します (CS0403)。 制約のない型パラメーターに null を割り当てると、コンパイラは型引数が null 値を受け取る参照型であることを保証できません。これは、 intstructなどの値型であり、 nullできない可能性があるためです。 このエラーを解決するには、任意の型に適切な既定値 (参照型の場合は null、値型の場合は 0 または空) を提供する default(T) を使用するか、参照型のセマンティクスが特に必要で、classの割り当てを許可する場合は、型パラメーターにnull制約を追加します。
  • class演算子 (as) を使用する場合は、または特定の型制約を追加します。 as演算子は、変換が失敗した場合にnullを返す安全な型キャストを実行しますが、値型をnullできないため、この動作は値型と互換性がありません。 制約のない型パラメーターで as を使用すると、コンパイラは型引数が値型ではないことを保証できないため、コードが拒否されます。 このエラーを修正するには、 class 制約または特定の参照型制約 ( where T : SomeClass など) を追加して、型パラメーターが常に、失敗したキャストの null 結果を適切に処理できる参照型であることを確認します。
  • 統合可能な型パラメーターを使用して同じジェネリック インターフェイスを複数回実装しないでください (CS0695)。 クラスが異なる型パラメーター ( class G<T1, T2> : I<T1>, I<T2> など) を使用してジェネリック インターフェイスを複数回実装すると、両方のパラメーター (G<int, int>) に対して同じ型でインスタンス化されるリスクがあります。これにより、クラスが実質的に 2 回 I<int> 実装されるため、競合が発生します。 このエラーを解決するには、インターフェイスを 1 回だけ実装するか、型パラメーターを再構築して統一を防ぐか、異なる特殊化に個別の非ジェネリック クラスを使用します。
  • 属性クラス (CS0698) からジェネリック型パラメーターを削除します。

    ジェネリック属性がサポートされているため、このエラーは現在のバージョンの C# では生成されなくなりました。

  • パブリックシグネチャまたはプロテクトシグネチャで使用される型引数が、少なくともそれらを使用するメンバーと同じくらいアクセス可能であることを確認します (CS9338)。 パブリックまたは保護されたジェネリック メンバーは、パブリックにアクセスできる型引数を使用する必要があります。 それ以外の場合、外部コードでメンバーの署名を正しく参照または使用できませんでした。 たとえば、public class Container<T>が内部型であるTがある場合、外部アセンブリはContainerを表示できますが、Tが表示されないため、適切に操作できません。 このエラーを修正するには、型引数をパブリックにするか、型引数のアクセシビリティに一致するようにメンバーを使用するメンバーのアクセシビリティを低下させます。

詳細については、「型パラメーター、既定値の式、および属性に関する制約」を参照してください。