コンストラクター宣言のエラーと警告を解決する

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

  • CS0514: "静的コンストラクターに、明示的な 'this' または 'base' コンストラクターの呼び出しを含めることはできません。"
  • CS0515: "アクセス修飾子を静的コンストラクターで使用できません。"
  • CS0516: "コンストラクター 'constructor' はそれ自体を呼び出すことはできません。"
  • CS0517: "'class' に基本クラスがないため、基本コンストラクターを呼び出すことができません。"
  • CS0522: "構造体は基底クラスのコンストラクターを呼び出すことができません。"
  • CS0526: "インターフェイスにコンストラクターを含めることはできません。"
  • CS0568: "構造体に明示的なパラメーターのないコンストラクターを含めることはできません。"
  • CS0710: "静的クラスにはコンストラクターを指定できません。"
  • CS0768: "コンストラクターで、それ自体を別のコンストラクターを通して呼び出すことはできません。"
  • CS8054: "列挙型は明示的なパラメーターなしのコンス トラクターを含めることはできません。"
  • CS8091: "extern にして、コンストラクター初期化子を含めることはできません。"
  • CS8861: "予期しない引数リスト。"
  • CS8862: "パラメーター リストを含む型で宣言されたコンストラクターには、'this' コンストラクター初期化子が必要です。"
  • CS8358: "'in' パラメーターがあるため、属性のコンストラクターを使用できません。"
  • CS8867: "基本型 '{0}' にアクセス可能なコピー コンストラクターが見つかりませんでした。"
  • CS8868: "レコード内のコピー コンストラクターは、ベースのコピー コンストラクターまたはパラメーターなしのオブジェクト コンストラクター (レコードがオブジェクトから継承している場合) を呼び出す必要があります。"
  • CS8878: "コピー コンストラクター '{0}' は、レコードが sealed ではないため、public または protected にする必要があります。"
  • CS8910: "プライマリ コンストラクターが、合成されたコピー コンストラクターと競合しています。"
  • CS8958: "パラメーターなしの構造体コンストラクターは 'パブリック' でなければなりません。"
  • CS8982: "パラメーター リストを含む "struct" で宣言されたコンストラクターには、プライマリ コンストラクターまたは明示的に宣言されたコンストラクターを呼び出す "this" 初期化子が必要です。"
  • CS8983: "フィールド初期化子を持つ 'struct' には、明示的に宣言されたコンストラクターを含める必要があります。"
  • CS9105: "このコンテキストでは、プライマリ コンストラクター パラメーターを使用できません。"
  • CS9106: "このコンテキストでは、識別子は型とパラメーターの間であいまいです。" クラスも同様です。*
  • CS9108: "匿名メソッド、ラムダ式、クエリ式、またはローカル関数内で、ref-like 型を持つパラメーターを使用することはできません。"
  • CS9109: "インスタンス メンバー内で、refout、または in プライマリ コンストラクター パラメーターを使用することはできません。"
  • CS9110: "インスタンス メンバー内で、ref-like 型を持つプライマリ コンストラクター パラメーターを使用することはできません。"
  • CS9111: "構造体のインスタンス メンバー内の匿名メソッド、ラムダ式、クエリ式、およびローカル関数は、プライマリ コンストラクター パラメーターにアクセスできません。"
  • CS9112: "構造体内の匿名メソッド、ラムダ式、クエリ式、およびローカル関数は、インスタンス メンバー内でも使用されるプライマリ コンストラクター パラメーターにアクセスできません。"
  • CS9114: "読み取り専用型のプライマリ コンストラクター パラメーターに代入することはできません (その型の init 専用セッター、または変数初期化子を除く)。"
  • CS9115: "読み取り専用型のプライマリ コンストラクター パラメーターを、書き込み可能な参照で返すことはできません。"
  • CS9116: "読み取り専用型のプライマリ コンストラクター パラメーターは、ref 値または out 値として使用できません (その型の init 専用セッター、または変数初期化子を除く)。"
  • CS9117: "読み取り専用型のプライマリ コンストラクター パラメーターのメンバーは変更できません (その型の init 専用セッター、または変数初期化子を除く)。"
  • CS9118: "読み取り専用型のプライマリ コンストラクター パラメーターのメンバーを、書き込み可能な参照で返すことはできません。"
  • CS9119: "読み取り専用型のプライマリ コンストラクター パラメーターのメンバーは、ref 値または out 値として使用できません (その型の init 専用セッター、または変数初期化子を除く)。"
  • CS9120: "プライマリ コンストラクター パラメーターを参照で返すことはできません。"
  • CS9121: "型の構造体プライマリ コンストラクター パラメーターにより、構造体レイアウトでサイクルが生じます。"
  • CS9122: "予期しないパラメーター リスト。"
  • CS9136: "インスタンス メンバー内で型のプライマリ コンストラクター パラメーターを使用することはできません。"

さらに、この記事では次の警告について説明します。

  • CS0824: "コンストラクター 'name' は、external としてマークされています。"
  • CS9107: "パラメーターは外側の型の状態にキャプチャされ、その値も基本コンストラクターに渡されます。値が基本クラスによってキャプチャされる場合もあります。"
  • CS9113: "パラメーターが未読です。"
  • CS9124: "パラメーターは外側の型の状態にキャプチャされ、その値もフィールド、プロパティ、またはイベントの初期化に使用されます。"
  • CS9179: "プライマリ コンストラクター パラメーターは基底のメンバーによってシャドウされます"

静的コンストラクター

  • CS0514: "静的コンストラクターに、明示的な 'this' または 'base' コンストラクターの呼び出しを含めることはできません。"
  • CS0515: "アクセス修飾子を静的コンストラクターで使用できません。"

型には、最大 1 つの静的コンストラクターを記述できます。 静的コンストラクターの宣言は、次の規則に従う必要があります。

  • 静的コンストラクターには static 修飾子がありますが、publicprotectedprivateinternal などのその他の修飾子はありません。
  • 静的コンストラクターはパラメーターなしのコンストラクターである必要があります。
  • 静的コンストラクターは、base() または this() を呼び出してはなりません。 基本クラスに静的コンストラクターが含まれている場合、ランタイムによって自動的に呼び出されます。

コンストラクターの宣言

  • CS0526: "インターフェイスにコンストラクターを含めることはできません。"
  • CS0710: "静的クラスにはコンストラクターを指定できません。"
  • CS8054: "列挙型は明示的なパラメーターなしのコンス トラクターを含めることはできません。"
  • CS8358: "'in' パラメーターがあるため、属性のコンストラクターを使用できません。"
  • CS8091: "コンストラクターを extern にして、コンストラクター初期化子を含めることはできません。"

コンストラクターは、class 型と struct 型 (record class 型と record struct 型を含む) のみが許可されます。 enum 型または interface 型で定義することはできません。 また、attribute クラス型では in パラメーターを宣言できません。 代わりに、パラメーターを値で渡します。

extern コンストラクターを宣言できますが、base() または this() コンストラクターの呼び出しを使用して、extern と宣言されたコンストラクターから別のコンストラクターを呼び出すことはできません。

さらに、コンストラクター宣言に対して次の警告を生成できます。

  • CS0824: "コンストラクターは external に設定されています。"

コンストラクターが extern とマークされている場合、コンパイラではコンストラクターの存在を保証できません。 したがって、コンパイラではこの警告が生成されます。

struct 型のコンストラクター

  • CS0568: "構造体に明示的なパラメーターのないコンストラクターを含めることはできません。"
  • CS8958: "パラメーターなしの構造体コンストラクターは 'パブリック' でなければなりません。"
  • CS8982: "パラメーター リストを含む "struct" で宣言されたコンストラクターには、プライマリ コンストラクターまたは明示的に宣言されたコンストラクターを呼び出す "this" 初期化子が必要です。"
  • CS8983: "フィールド初期化子を持つ 'struct' には、明示的に宣言されたコンストラクターを含める必要があります。"

C# の最近の機能では、struct 型に対する以前の制限が除去されています。 CS0568 は、以前のバージョンの C# でパラメーターなしのインスタンス コンストラクターを宣言すると生成されます。 C# 10 を使うと、明示的なパラメーターなしのインスタンス コンストラクターを宣言できます。 その明示的なパラメーターなしのコンストラクターは、public である要があります。 structフィールド初期化子を宣言する場合は、明示的なインスタンス コンストラクターも宣言する必要があります。 このコンストラクターは、空の本体を含むパラメーターなしのコンストラクターにすることができます。

struct 型がプライマリ コンストラクター (record struct 型を含む) を宣言する場合、パラメーターなしのコンストラクターを除く他のすべてのインスタンス コンストラクターは、this() を使ってプライマリ コンストラクターまたは明示的に宣言された別のコンストラクターを呼び出す必要があります。

base および this を使用したコンストラクターの呼び出し

  • CS0516: "コンストラクターはそれ自体を呼び出すことはできません。"
  • CS0517: "'class' に基本クラスがないため、基本コンストラクターを呼び出すことができません。"
  • CS0522: "構造体は基底クラスのコンストラクターを呼び出すことができません。"
  • CS0768: "コンストラクターで、それ自体を別のコンストラクターを通して呼び出すことはできません。"

base()this() を使用して、コンストラクターで同じ型または基本型の別のコンストラクターを呼び出すことができます。 コンストラクターを呼び出すと、重複するコンストラクター ロジックを最小限に抑えることができます。 this() または base() を使用して別のコンストラクターを呼び出すときは、次の規則に従う必要があります。

  • コンストラクターでは、別のコンストラクターを介して直接または間接的にそれ自体を呼び出すことはできません。 たとえば、次のようなコードは無効です。

    public class C
    {
      public C() : this() // Error!
      {
      }
    }
    
    public class C2
    {
      public class C2() : this(10) {}
    
      public class C2(int capacity) : this() 
      {
          _capacity = capacity;
      }
    
      private int _capacity;
    }
    ``
    
    
  • 構造体型では base() を呼び出すことはできません。 いずれも System.Object にすることはできません。

レコードとコピー コンストラクター

  • CS8867: "基本データ型に、アクセス可能なコピー コンストラクターが見つかりませんでした。"
  • CS8868: "レコード内のコピー コンストラクターは、ベースのコピー コンストラクターまたはパラメーターなしのオブジェクト コンストラクター (レコードがオブジェクトから継承している場合) を呼び出す必要があります。"
  • CS8878: "コピー コンストラクターは、レコードが sealed ではないため、public または protected にする必要があります。"
  • CS8910: "プライマリ コンストラクターが、合成されたコピー コンストラクターと競合しています。"

record 修飾子を struct 型または class 型に追加すると、レコードが作成されます。 レコードには、コンパイラによって合成されたコピー コンストラクターが含まれます。 明示的なコピー コンストラクターは自分で記述できますが、次の規則に従う必要があります。

  • コピー コンストラクターは、型が sealed である場合を除き、public または protected である必要があります。
  • コピー コンストラクターでは、基本クラスが System.Object でない限り、base() コピー コンストラクターを呼び出す必要があります。
  • さらに、基本型にはコピー コンストラクターが必要です。 record 型には、常にコピー コンストラクターが含まれます。

プライマリ コンストラクターの宣言

クラスと構造体のプライマリ コンストラクターに関する 1 つ以上の規則にプライマリ コンストラクターが違反すると、コンパイラでは次のエラーが出力されます。

  • CS8861: "予期しない引数リスト。"
  • CS8862: "パラメーター リストを含む型で宣言されたコンストラクターには、'this' コンストラクター初期化子が必要です。"
  • CS9105: "このコンテキストでは、プライマリ コンストラクター パラメーターを使用できません。"
  • CS9106: "このコンテキストでは、識別子は型とパラメーターの間であいまいです。"
  • CS9108: "匿名メソッド、ラムダ式、クエリ式、またはローカル関数内で、ref-like 型を持つパラメーターを使用することはできません。"
  • CS9109: "インスタンス メンバー内で、refout、または in プライマリ コンストラクター パラメーターを使用することはできません。"
  • CS9110: "インスタンス メンバー内で、ref-like 型を持つプライマリ コンストラクター パラメーターを使用することはできません。"
  • CS9111: "構造体のインスタンス メンバー内の匿名メソッド、ラムダ式、クエリ式、およびローカル関数は、プライマリ コンストラクター パラメーターにアクセスできません。"
  • CS9112: "構造体内の匿名メソッド、ラムダ式、クエリ式、およびローカル関数は、インスタンス メンバー内でも使用されるプライマリ コンストラクター パラメーターにアクセスできません。"
  • CS9114: "読み取り専用型のプライマリ コンストラクター パラメーターに代入することはできません (その型の init 専用セッター、または変数初期化子を除く)。"
  • CS9115: "読み取り専用型のプライマリ コンストラクター パラメーターを、書き込み可能な参照で返すことはできません。"
  • CS9116: "読み取り専用型のプライマリ コンストラクター パラメーターは、ref 値または out 値として使用できません (その型の init 専用セッター、または変数初期化子を除く)。"
  • CS9117: "読み取り専用型のプライマリ コンストラクター パラメーターのメンバーは変更できません (その型の init 専用セッター、または変数初期化子を除く)。"
  • CS9118: "読み取り専用型のプライマリ コンストラクター パラメーターのメンバーを、書き込み可能な参照で返すことはできません。"
  • CS9119: "読み取り専用型のプライマリ コンストラクター パラメーターのメンバーは、ref 値または out 値として使用できません (その型の init 専用セッター、または変数初期化子を除く)。"
  • CS9120: "プライマリ コンストラクター パラメーターを参照で返すことはできません。"
  • CS9121: "型の構造体プライマリ コンストラクター パラメーターにより、構造体レイアウトでサイクルが生じます。"
  • CS9122: "予期しないパラメーター リスト。"
  • CS9124: "パラメーターは外側の型の状態にキャプチャされ、その値もフィールド、プロパティ、またはイベントの初期化に使用されます。"
  • CS9136: "インスタンス メンバー内で型のプライマリ コンストラクター パラメーターを使用することはできません。"

プライマリ コンストラクター パラメーターは、その型の本体のスコープ内にあります。 コンパイラでは、メンバーまたはフィールド初期化子で使用するパラメーターを格納するフィールドを合成できます。 プライマリ コンストラクター パラメーターはフィールドにコピーできるため、次の制限が適用されます。

  • プライマリ コンストラクターは structclass 型で宣言できますが、interface 型では宣言できません。
  • プライマリ コンストラクター パラメーターは、プライマリ コンストラクターの一部として使用する場合を除き、base() コンストラクターの呼び出しで使用することはできません。
  • ラムダ式、クエリ式、またはローカル関数では、ref struct 型のプライマリ コンストラクター パラメーターにアクセスできません。
  • 型が ref struct でない場合、インスタンス メンバーでは ref struct パラメーターにアクセスできません。
  • ref struct 型では、inref、または out 修飾子を持つプライマリ コンストラクター パラメーターは、インスタンス メソッドまたはプロパティ アクセサーで使用できません。

構造体型には、プライマリ コンストラクター パラメーターに対して次の追加の制限があります。

  • プライマリ コンストラクター パラメーターをラムダ式、クエリ式、またはローカル関数でキャプチャすることはできません。
  • プライマリ コンストラクター パラメーターを参照 (ref 戻り値または readonly ref 戻り値) で返すことはできません。

読み取り専用の構造体型には、プライマリ コンストラクター パラメーターに対して次の追加の制限があります。

  • プライマリ コンストラクター パラメーターとそのメンバーを readonly 構造体で再割り当てすることはできません。
  • プライマリ コンストラクター パラメーターとそのメンバーを readonly 構造体で ref で返すことはできません。
  • プライマリ コンストラクター パラメーターとそのメンバーを、任意のメソッドに対する ref 引数または out 引数にすることはできません。

いずれの場合も、プライマリ コンストラクター パラメーターに対する制限は、これらの型のデータ フィールドに対する制限と一致します。 これは、プライマリ コンストラクター パラメーターがその型の合成フィールドに変換される可能性があるためです。 したがって、プライマリ コンストラクター パラメーターは、その合成フィールドに適用される規則に従う必要があります。

派生プライマリ コンストラクターは、基底コンストラクターにパラメータを指定して、基底プライマリ コンストラクターを呼び出します。 派生コンストラクター宣言からのパラメータ名を使用する必要があります。

これらの警告により、キャプチャまたはシャドウされたプライマリ コンストラクター パラメーターに関するガイダンスが提供されます。

  • CS9107: "パラメーターは外側の型の状態にキャプチャされ、その値も基本コンストラクターに渡されます。値が基本クラスによってキャプチャされる場合もあります。"この警告は、コードにプライマリ コンストラクター パラメーターの 2 つのコピーが割り当てられている可能性があることを示します。 パラメーターは基本クラスに渡されるため、基本クラスで使用される可能性があります。 派生クラスはそれにアクセスするため、同じパラメーターの 2 番目のコピーが含まれる可能性があります。 その追加のストレージは、意図するものではない可能性があります。
  • CS9113: "パラメーターが未読です。"この警告は、クラスによってプライマリ コンストラクターが参照されることも、基本プライマリ コンストラクターに渡されることもないことを示します。 これは必要ない可能性があります。
  • CS9124: "パラメーターは外側の型の状態にキャプチャされ、その値もフィールド、プロパティ、またはイベントの初期化に使用されます。"この警告は、入れ子になった型のコンストラクター パラメーターも外側の型によってキャプチャされることを示します。 パラメーターは 2 回格納される可能性があります。
  • CS9179: "プライマリ コンストラクター パラメーターは基底のメンバーによってシャドウされます"