次の方法で共有


ユーザー定義演算子宣言のエラーと警告を解決する

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

  • CS0056: アクセシビリティに一貫性がありません。戻り値の型 'type' は、演算子 'operator' よりもアクセシビリティが低い
  • CS0057: アクセシビリティに一貫性がありません:パラメーター型 'type' は演算子 'operator' よりもアクセスできない
  • CS0215: 演算子 True または False の戻り値の型はブール値である必要があります
  • CS0216: 演算子 'operator' には、一致する演算子 'missing_operator' も定義する必要があります
  • CS0217: ショートサーキット演算子として適用できるようにするには、ユーザー定義の論理演算子 ('operator') は、その 2 つのパラメーターの型と同じ戻り値の型を持つ必要があります。
  • CS0218: 型 ('type') には、演算子 true と演算子 false の宣言が含まれている必要があります
  • CS0448: ++演算子または--演算子の戻り値の型は、包含型であるか、包含型から派生している必要があります
  • CS0552: '変換ルーチン' : ユーザー定義のインターフェイス間の変換
  • CS0553: '変換ルーチン' : 基底クラスに対するユーザー定義の変換
  • CS0554: '変換ルーチン' : 派生クラスに対するユーザー定義の変換
  • CS0555: ユーザー定義演算子は、囲んでいる型のオブジェクトを受け取り、その型のオブジェクトへの変換はできません
  • CS0556: ユーザー定義変換は、囲む型に変換するか、または囲む型から変換する必要があります
  • CS0557: 型でのユーザー定義変換の重複
  • CS0558: ユーザー定義演算子を静的およびパブリックとして宣言する必要があります
  • CS0559: ++演算子または -- 演算子のパラメーター型は、包含型である必要があります
  • CS0562: 単項演算子のパラメーターは、包含型である必要があります
  • CS0563: 二項演算子のパラメーターの 1 つが包含型である必要があります
  • CS0564: オーバーロードされたシフト演算子の最初のオペランドは、含まれている型と同じ型を持つ必要があり、2 番目のオペランドの型は int である必要があります
  • CS0567: インターフェイスに演算子を含めることはできません
  • CS0590: ユーザー定義演算子は void を返すことができません
  • CS0660: 型はoperator ==またはoperator !=を定義しますが、Object.Equals(object o)をオーバーライドしません
  • CS0661: 型はoperator ==またはoperator !=を定義しますが、Object.GetHashCode()をオーバーライドしません
  • CS0715: 静的クラスにユーザー定義演算子を含めることはできません
  • CS1037: オーバーロード可能な演算子が必要です
  • CS1553: 宣言が無効です。その代わりに 'modifier 演算子 <dest-type> (...' を使用してください
  • CS8930: ユーザー定義演算子の明示的な実装は静的である必要があります。
  • CS8931: 型のインターフェイス メンバーを実装するには、明示的な実装をパブリックとして宣言する必要があります。
  • CS9023: 演算子をチェックできません。
  • CS9024: 演算子をオフにすることはできません。
  • CS9025: 演算子では、一致するチェックされていないバージョンも宣言する必要があります。
  • CS9308: ユーザー定義演算子はパブリックとして宣言する必要があります。
  • CS9310: この演算子の戻り値の型は void である必要があります。
  • CS9311: 型はインターフェイス メンバーを実装しません。メンバーの 1 つが演算子ではないため、型はメンバーを実装できません。
  • CS9312: 型は、継承されたメンバーの 1 つが演算子ではないため、オーバーライドできません。
  • CS9313: オーバーロードされた複合代入演算子は、1 つのパラメーターを受け取ります。
  • CS9340: オペランドに演算子を適用できません。最も適用できない候補が表示されます。
  • CS9341: オペランドに演算子を適用できません。最も適用できない候補が表示されます。
  • CS9342: 演算子の解決は、次のメンバー間であいまいです。

オペレーター署名の要件

  • CS0448: ++演算子または--演算子の戻り値の型は、包含型であるか、包含型から派生している必要があります。
  • CS0559: ++演算子または--演算子のパラメーター型は、包含型である必要があります。
  • CS0562: 単項演算子のパラメーターは、包含型である必要があります。
  • CS0563: 二項演算子のパラメーターの 1 つが包含型である必要があります。
  • CS0564: オーバーロードされたシフト演算子の最初のオペランドは、含む型と同じ型を持つ必要があり、2 番目のオペランドの型は int である必要があります。
  • CS0567: インターフェイスに演算子を含めることはできません。
  • CS0590: ユーザー定義演算子は void を返すことはできません。
  • CS9310: この演算子の戻り値の型は void である必要があります。
  • CS9340: オペランドに演算子を適用できません。最も適用できない候補が表示されます。
  • CS9341: オペランドに演算子を適用できません。最も適用できない候補が表示されます。
  • CS9342: 演算子の解決は、次のメンバー間であいまいです。

正しいシグネチャを持つ演算子を宣言するには、特定の演算子の種類に関する次の要件に従います。 詳細については、「演算子の オーバーロード」を参照してください。

  • ++演算子と--演算子 (CS0448) から、包含型 (または派生型) を返します。
  • ++演算子と--演算子 (CS0559) のパラメーターとして、包含型を使用します。
  • 単項演算子 (CS0562) のパラメーターとして、包含型を使用します。
  • 2 項演算子 (CS0563) に、含まれる型を少なくとも 1 つのパラメーターとして含めます。
  • 最初のパラメーターとして包含型を使用し、シフト演算子の 2 番目のパラメーターとして int します (CS0564)。
  • インターフェイスで演算子を宣言しないでください (CS0567)。 インターフェイスに演算子の実装を含めることはできません。
  • ほとんどの演算子 (CS0590) から非 void 型を返します。ただし、 void 戻り値を必要とする特定の演算子 (CS9310) を除く)。
  • 解決エラー (CS9340、CS9341) を回避するために、正しいパラメーター型を受け入れる演算子オーバーロードを指定します。
  • 明示的なキャストを使用するか、より具体的なオーバーロードを提供することで、演算子呼び出しの曖昧さを解消します (CS9342)。

Important

静的二項演算子と対応するインスタンス複合代入演算子のシグネチャ要件は異なります。 署名が目的の宣言と一致していることを確認します。

署名エラーの例を次に示します。

class C1
{
    public static int operator ++(C1 c) => 0;   // CS0448
    public static C1 operator --(C1 c) => null;   // OK
}
public class C2
{
    public static implicit operator int(C2 x) => 0;
    public static implicit operator C2(int x) => new C2();
    public static int operator ++(int aa) => 0;  // CS0559
}
public class C3
{
    public static implicit operator int(C3 x) => 0;
    public static implicit operator C3(int x) => null;
    public static C3 operator +(int aa) => 0;   // CS0562
}
public class C4
{
    public static implicit operator int(C4 x) => 0;
    public static implicit operator C4(int x) => null;
    public static int operator +(int aa, int bb) => 0;   // CS0563
}
class C5
{
    // To correct, change second operand to int, like so:
    // public static int operator << (C c1, int c2)
    public static int operator <<(C5 c1, C5 c2) => 0; // CS0564
}
interface IA
{
    int operator +(int aa, int bb);   // CS0567
}
public class C6
{
    public static void operator +(C6 A1, C6 A2) { }  // CS0590
}

演算子宣言の要件

  • CS0558: ユーザー定義演算子は、静的およびパブリックとして宣言する必要があります。
  • CS0715: 静的クラスにユーザー定義演算子を含めることはできません。
  • CS1037: オーバーロード可能な演算子が必要です。
  • CS1553: 宣言が有効ではありません。その代わりに、'modifier 演算子 <dest-type> (...' を使用してください。
  • CS8930: ユーザー定義演算子の明示的な実装は静的である必要があります。
  • CS8931: 型のインターフェイス メンバーを実装するには、明示的な実装をパブリックとして宣言する必要があります。
  • CS9308: ユーザー定義演算子はパブリックとして宣言する必要があります。

演算子を正しく宣言するには、修飾子と包含型に関する次の要件に従います。 詳細については、「 演算子のオーバーロード 」および 「ユーザー定義変換演算子」を参照してください。

  • static修飾子とpublic修飾子 (CS0558CS9308) の両方で演算子を宣言します。
  • 静的クラスで演算子を宣言しないでください (CS0715)。 通常のクラスまたは構造体を使用します。
  • 有効でオーバーロード可能な演算子シンボル (CS1037) を使用します。
  • 変換演算子の正しい構文に従います: public static implicit/explicit operator <dest-type>(<source-type> parameter) (CS1553)。
  • 演算子の明示的なインターフェイス実装が static (CS8930) および public (CS8931) であることを確認します。

宣言エラーの例を次に示します。

public class C
{
    static implicit operator int(C aa) => 0;   // CS0558, add public
}
public static class C1
{
    public static int operator +(C1 c) => 0;  // CS0715
}
class C2
{
    public static int implicit operator (C2 f) => 6;   // CS1553
}

アクセシビリティに一貫性がない

  • CS0056: アクセシビリティに一貫性がありません。戻り値の型 'type' は、演算子 'operator' よりもアクセシビリティが低くなります。
  • CS0057: アクセシビリティに一貫性がありません。パラメーター型 'type' は、演算子 'operator' よりもアクセシビリティが低くなります。

演算子宣言で一貫したアクセシビリティを確保するには、パブリック演算子で使用されるすべての型をパブリックにアクセスできるようにします。 詳細については、「 アクセス修飾子」を参照してください。

  • 戻り値の型に、演算子 (CS0056) と少なくとも同じアクセシビリティがあることを確認します。
  • パラメーター型のアクセシビリティが演算子 (CS0057) と少なくとも同じであることを確認します。

public演算子を宣言する場合、パラメーターまたは戻り値として使用されるすべての型にもパブリックにアクセスできる必要があります。

次の例は、アクセシビリティ エラーを示しています。

class C { }

public class C2
{
    public static implicit operator C(C2 a) => new C();   // CS0056
}

public class C3
{
    public static implicit operator C3(C c) => new C3();   // CS0057
}

ユーザー定義の変換制限

  • CS0552: インターフェイスへのまたはインターフェイスからのユーザー定義変換。
  • CS0553: 基底クラスに対するユーザー定義の変換。
  • CS0554: 派生クラスへの、または派生クラスからのユーザー定義の変換。
  • CS0555: ユーザー定義演算子は、外側の型のオブジェクトを受け取って、外側の型のオブジェクトに変換することはできません。
  • CS0556: ユーザー定義の変換は、囲んでいる型に変換するか、または囲んでいる型から変換する必要があります。
  • CS0557: 型のユーザー定義変換が重複しています。

有効なユーザー定義変換演算子を作成するには、次の制限に従います。 詳細については、「 ユーザー定義変換演算子」を参照してください。

  • インターフェイスとの間の変換を定義しないでください (CS0552)。 代わりに明示的なインターフェイス実装を使用してください。
  • 基底クラスとの間の変換は定義しないでください (CS0553)。 変換は継承によって既に存在します。
  • 派生クラスとの間の変換を定義しないでください (CS0554)。 変換は継承によって既に存在します。
  • 外側の型からそれ自体への変換を定義しないでください (CS0555)。 この変換は暗黙的です。
  • 変換の少なくとも 1 つの型が外側の型 (CS0556) であることを確認します。 2 つの外部型間の変換を定義することはできません。
  • 重複する変換を定義しないでください (CS0557)。 各変換演算子は一意である必要があります。

変換制限エラーの例を次に示します。

public interface I
{
}
public class C
{
    public static implicit operator I(C aa) => default;// CS0552
}

public class B
{
}
public class D : B
{
    public static implicit operator B(D aa) => new B();// CS0553
}

public class B2
{
    // delete the conversion routine to resolve CS0554
    public static implicit operator B2(D2 d) => new B2();// CS0554
}
public class D2 : B2 { }

public class C2
{
    public static implicit operator C2(C2 aa) => new C2();   // CS0555
}

public class C3
{
    public static implicit operator int(byte aa) => 0;   // CS0556
}

public class C4
{
    public static implicit operator int(C4 aa) => 0;

    // CS0557, delete duplicate
    public static explicit operator int(C4 aa) => 0;
}

ブール演算子と短絡演算子

  • CS0215: 演算子 true または false の戻り値の型はブール値である必要があります。
  • CS0216: 演算子には、一致する演算子も定義する必要があります。
  • CS0217: ショートサーキット演算子として適用するには、ユーザー定義論理演算子の戻り値の型が 2 つのパラメーターの型と同じである必要があります。
  • CS0218: 型には、演算子 true と演算子 false の宣言が含まれている必要があります。

論理演算子を正しく定義するには、これらのペアリングと署名の要件に従います。 詳細については、「 true 演算子と false 演算子ブール論理演算子およびユーザー定義の条件付き論理演算子」を参照してください。

  • bool および operator true (operator false) からを返します。
  • 必要なペア演算子 (CS0216) を定義します。
    • operator ==operator !=を必要とします
    • operator <operator > を必要とする
    • operator <=operator >=を必要とします
    • operator true が必要です operator false
  • 戻り値の型を、カスタム型 (&) で動作する短絡演算子 (|および) のパラメーター型と一致させます。
  • operator trueoperator false (&&) などのブール型でカスタム型を使用する場合は、||の両方を実装します。

論理演算子エラーの例を次に示します。

class C
{
    public static int operator true(C c) => 0;   // CS0215
    public static int operator false(C c) => 0; // CS0215
}

class C2
{
    public static bool operator ==(C2 left, C2 right) => left.Equals(right);   // CS0216

    public override bool Equals(object? o) => base.Equals(o);
    public override int GetHashCode() => base.GetHashCode();
}

public class C3
{
    public static bool operator true(C3 f) => false;
    public static bool operator false(C3 f) => true;
    public static implicit operator int(C3 x) => 0;
    public static int operator &(C3 f1, C3 f2) => new C3();  // CS0217
}

public class C4
{
    public static implicit operator int(C4 x) => 0;
    public static C4 operator &(C4 f1, C4 f2) => new C4();

    public static void Main()
    {
        C4 f = new C4();
        int i = f && f;   // CS0218, requires operators true and false
    }
}

チェックされた演算子

  • CS9023: 演算子をチェックされるように設定できません
  • CS9024: 演算子をオフにすることはできません
  • CS9025: Checked 演算子では、一致するチェックされていないバージョンも宣言する必要があります

チェックされた演算子を正しく使用するには、次の要件に従います。 詳細については、「 算術演算子 」および「 ユーザー定義のチェック演算子」を参照してください。

  • サポートされている算術演算子 (checkedunchecked+-*/、および明示的な変換 ) にのみ、++または--キーワードを適用します (CS9023CS9024)。
  • checked 演算子 (CS9025) を宣言するときに、チェック済みバージョンとチェックされていないバージョンの両方を指定します。 コンパイラは両方とも異なるコンテキストを処理する必要があります。

インターフェイスと継承の要件

  • CS9311: 型はインターフェイス メンバーを実装しません。型の 1 つが演算子でないため、メンバーを実装できません
  • CS9312: 型は、そのうちの 1 つが演算子ではないので、継承されたメンバーをオーバーライドできません
  • CS9313: オーバーロードされた複合代入演算子は 1 つのパラメーターを受け取ります

演算子を正しく実装してオーバーライドするには、次の要件に従います。 詳細については、「演算子の オーバーロードインターフェイス」を参照してください。

  • 演算子の宣言がインターフェイス メンバーのシグネチャと型と一致していることを確認します (CS9311)。 演算子は、非演算子メンバーを実装できません。
  • オーバーライドされる継承メンバーも演算子であることを確認します (CS9312)。 演算子は、非演算子メンバーをオーバーライドできません。
  • 1 つのパラメーターを使用して複合代入演算子を宣言します (CS9313)。 左オペランドは暗黙的に this

等値演算子

  • CS0660: 型は演算子 == または演算子 != を定義しますが、Object.Equals(object o) をオーバーライドしません
  • CS0661: 型は演算子 == または演算子 != を定義しますが、Object.GetHashCode() をオーバーライドしません

等価性を正しく実装するには、カスタム等値演算子を定義するときに、対応する Object メソッドをオーバーライドします。 詳細については、「型と等値演算子の値の等価性を定義する方法」を参照してください。

  • Object.Equalsまたはoperator == (operator !=) を定義するときに、をオーバーライドします。
  • Object.GetHashCodeまたはoperator == (operator !=) を定義するときに、をオーバーライドします。

これらのメソッドをオーバーライドすると、異なる API とコレクション型間で一貫した等値動作が保証されます。