Sdílet prostřednictvím


Řešení chyb a upozornění v deklarací operátoru definovaných uživatelem

Tento článek se zabývá následujícími chybami kompilátoru:

  • CS0056: Nekonzistentní přístupnost: návratový typ "typ" je méně přístupný než operátor 'operator'
  • CS0057: Nekonzistentní přístupnost: typ parametru 'type' je méně přístupný než operátor 'operator'
  • CS0215: Návratový typ operátoru Pravda nebo Nepravda musí být bool
  • CS0216: Operátor "operator" vyžaduje, aby byl definován také odpovídající operátor "missing_operator".
  • CS0217: Aby bylo možné použít jako operátor krátkého okruhu, musí mít uživatelem definovaný logický operátor ("operátor") stejný návratový typ jako typ jeho 2 parametrů.
  • CS0218: Typ ('type') musí obsahovat deklarace operátoru true a operátor false
  • CS0448: Návratový typ pro ++ nebo -- operátor musí být obsahující typ nebo odvozený z tohoto obsahu typu
  • CS0552: 'konverzní rutina' : uživatelem definovaný převod do/z rozhraní
  • CS0553: "konverzní rutina" : uživatelem definovaný převod na/z základní třídy
  • CS0554: 'konverzní rutina' : uživatelem definovaný převod na/z odvozené třídy
  • CS0555: Uživatelem definovaný operátor nemůže převzít objekt ohraničujícího typu a převést na objekt ohraničujícího typu.
  • CS0556: Převod definovaný uživatelem musí převést na nebo z uzavřeného typu
  • CS0557: Duplicitní uživatelsky definovaná konverze v rámci typu
  • CS0558: Operátor definovaný uživatelem musí být deklarován jako statický a veřejný.
  • CS0559: Typ parametru pro operátor ++ nebo -- musí být typ obsahující.
  • CS0562: Parametr unárního operátoru musí být obsahující typ.
  • CS0563: Jedním z parametrů binárního operátoru musí být typ obsahující
  • CS0564: První operand přetíženého operátoru posunu musí mít stejný typ jako obsahující typ a typ druhého operandu musí být int
  • CS0567: Rozhraní nemohou obsahovat operátory
  • CS0590: Uživatelem definované operátory nemůžou vracet void
  • CS0660: Typ definuje operator == nebo operator !=, ale nepřepíše Object.Equals(object o)
  • CS0661: Typ definuje operator == nebo operator !=, ale nepřepíše Object.GetHashCode()
  • CS0715: Statické třídy nemohou obsahovat uživatelem definované operátory
  • CS1037: Byl očekáván přetížitelný operátor
  • CS1553: Deklarace není platná; použijte modifikační operátor <dest-type> (...). namísto
  • CS8930: Explicitní implementace uživatelem definovaného operátoru musí být statická.
  • CS8931: Explicitní implementace musí být deklarována jako veřejná pro implementaci člena rozhraní typu.
  • CS9023: Operátor nelze zkontrolovat.
  • CS9024: Operátor nelze nastavit jako nezjištěný.
  • CS9025: Operátor vyžaduje, aby byla deklarována také odpovídající nekontrolovaná verze.
  • CS9308: Uživatelem definovaný operátor musí být deklarován jako veřejný.
  • CS9310: Návratový typ tohoto operátoru musí být neplatný.
  • CS9311: Typ neimplementuje člena rozhraní. Typ nemůže implementovat člen, protože jeden z nich není operátor.
  • CS9312: Typ nemůže přepsat zděděný člen, protože jeden z nich není operátor.
  • CS9313: Přetížený operátor složeného přiřazení přebírá jeden parametr.
  • CS9340: Operátor nelze použít na operandy. Bude zobrazen nejbližší kandidát, který nelze použít.
  • CS9341: Operátor nelze použít pro operand. Zobrazuje se nejbližší neaplikovatelný kandidát.
  • CS9342: Rozlišení operátoru je nejednoznačné mezi následujícími členy.

Požadavky na podpis operátora

  • CS0448: Návratový typ operátoru ++ nebo -- musí být obsažený typ nebo odvozený z obsaženého typu.
  • CS0559: Typ parametru pro ++ nebo -- operátor musí být obsahující typ.
  • CS0562: Parametr unárního operátoru musí být obsahující typ.
  • CS0563: Jeden z parametrů binárního operátoru musí být obsahující typ.
  • CS0564: První operand přetíženého operátoru posunu musí mít stejný typ jako typ obsahujícího a typ druhého operandu musí být int.
  • CS0567: Rozhraní nemohou obsahovat operátory.
  • CS0590: Uživatelem definované operátory nemůžou vracet void.
  • CS9310: Návratový typ tohoto operátoru musí být neplatný.
  • CS9340: Operátor nelze použít na operandy. Zobrazen je nejbližší nepoužitelný kandidát.
  • CS9341: Operátor nelze použít na operand. Zobrazen bude nejbližší nevyhovující kandidát.
  • CS9342: Rozlišení operátoru je nejednoznačné mezi následujícími členy.

Chcete-li deklarovat operátory se správnými podpisy, postupujte podle těchto požadavků pro konkrétní typ operátoru. Další informace naleznete v tématu Přetížení operátoru.

  • Vrátí obsahující typ (nebo odvozený typ) z operátorů ++ a -- (CS0448).
  • Jako parametr pro operátory ++ a -- použijte typ, který obsahuje daný obsah (CS0559).
  • Jako parametr použijte typ obsahující unární operátory (CS0562).
  • Zahrnout obsahující typ jako alespoň jeden parametr v binárních operátorech (CS0563).
  • Jako první parametr použijte obsahující typ a jako druhý parametr použijte int pro operátory shift (CS0564).
  • Neuklarujte operátory v rozhraních (CS0567). Rozhraní nemohou obsahovat implementace operátorů.
  • Vrátí ne-voidový typ z většiny operátorů (CS0590), s výjimkou konkrétních operátorů, které vyžadují vrácení void (CS9310).
  • Zadejte přetížení operátorů, které přijímají správné typy parametrů, aby nedocházelo k calošení resolučního procesu (CS9340, CS9341).
  • Odstraňte nejednoznačnost volání operátoru pomocí explicitního přetypování nebo poskytnutím konkrétnějšího přetížení (CS9342).

Důležité

Požadavky na podpis pro statické binární operátory a odpovídající operátory složeného přiřazení instance jsou odlišné. Ujistěte se, že podpis odpovídá požadované deklaraci.

Následující příklad ukazuje chyby podpisu:

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
}

Požadavky na deklaraci operátoru

  • CS0558: Operátor definovaný uživatelem musí být deklarován jako statický a veřejný.
  • CS0715: Statické třídy nemohou obsahovat uživatelem definované operátory.
  • CS1037: Byl očekáván přetížitelný operátor.
  • CS1553: Deklarace není platná; použijte modifikační operátor <dest-type> (...). namísto.
  • CS8930: Explicitní implementace uživatelem definovaného operátoru musí být statická.
  • CS8931: Explicitní implementace musí být deklarována jako veřejná pro implementaci člena rozhraní v rámci daného typu.
  • CS9308: Uživatelem definovaný operátor musí být deklarován jako veřejný.

Chcete-li deklarovat operátory správně, postupujte podle těchto požadavků pro modifikátory a obsahující typy. Další informace naleznete v tématu Operátor přetížení a Uživatelem definované převodní operátory.

  • Deklarujte operátory pomocí staticpublic modifikátorů (CS0558, CS9308).
  • Ne deklarujte operátory v statických třídách (CS0715). Používejte běžné třídy nebo struktury.
  • Použijte platné, přetížitelné symboly operátoru (CS1037).
  • Postupujte podle správné syntaxe pro operátory převodu: public static implicit/explicit operator <dest-type>(<source-type> parameter) (CS1553).
  • Ujistěte se, že explicitní implementace rozhraní operátorů jsou static (CS8930) a public (CS8931).

Následující příklad ukazuje chyby deklarace:

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
}

Nekonzistentní přístupnost

  • CS0056: Nekonzistentní přístupnost: návratový typ "typ" je méně přístupný než operátor 'operator'.
  • CS0057: Nekonzistentní přístupnost: typ parametru 'type' je méně přístupný než operátor 'operator'.

Chcete-li zajistit konzistentní přístupnost v deklaraci operátorů, zpřístupnit všechny typy používané ve veřejných operátorech veřejně. Další informace naleznete v tématu Modifikátory accessu.

  • Ujistěte se, že návratové typy mají alespoň stejnou přístupnost jako operátor (CS0056).
  • Zajistěte, aby typy parametrů měly alespoň stejnou přístupnost jako operátor (CS0057).

Když deklarujete public operátor, musí být všechny typy používané jako parametry nebo návratové hodnoty také veřejně přístupné.

Následující příklad ukazuje chyby přístupnosti:

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
}

Uživatelsky definovaná omezení převodu

  • CS0552: Uživatelem definovaný převod na/z rozhraní.
  • CS0553: Převod definovaný uživatelem na/ze základní třídy.
  • CS0554: Převod definovaný uživatelem na/z odvozené třídy.
  • CS0555: Uživatelem definovaný operátor nemůže vzít objekt ohraničujícího typu a převést na objekt ohraničujícího typu.
  • CS0556: Převod definovaný uživatelem musí převést na nebo z obklopujícího typu.
  • CS0557: Duplicitní uživatelem definovaný převod typu.

Pokud chcete vytvořit platné uživatelem definované operátory převodu, postupujte podle těchto omezení. Další informace naleznete v tématu Uživatelem definované operátory převodu.

  • Nedefinujte převody na rozhraní ani z rozhraní (CS0552). Místo toho použijte explicitní implementace rozhraní.
  • Nedefinujte převody do nebo ze základních tříd (CS0553). Převod již existuje prostřednictvím dědičnosti.
  • Nedefinujte převody na odvozené třídy nebo z nich (CS0554). Převod již existuje prostřednictvím dědičnosti.
  • Nedefinujte převody z obalujícího typu do sebe (CS0555). Tento převod je implicitní.
  • Ujistěte se, že alespoň jeden typ v převodu je obalující typ (CS0556). Převody mezi dvěma externími typy nelze definovat.
  • Nedefinujte duplicitní převody (CS0557). Každý operátor převodu musí být jedinečný.

Následující příklad ukazuje chyby omezení převodu:

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;
}

Logické operátory a operátory zkratek

  • CS0215: Návratový typ operátoru true nebo false musí být bool.
  • CS0216: Operátor vyžaduje, aby byl definován také odpovídající operátor.
  • CS0217: Aby bylo možné použít jako operátor zkratového okruhu, musí mít uživatelem definovaný logický operátor stejný návratový typ jako typ jeho 2 parametrů.
  • CS0218: Typ musí obsahovat deklarace operátoru true a operátor false.

Pokud chcete správně definovat logické operátory, postupujte podle těchto požadavků na párování a podpis. Další informace naleznete v tématu true a false operátory, logické operátory a uživatelem definované podmíněné logické operátory.

  • Vrátit bool od operator true a operator false (CS0215).
  • Definovat požadované spárované operátory (CS0216):
    • operator == požaduje operator !=
    • operator < požaduje operator >
    • operator <= požaduje operator >=
    • operator true požaduje operator false
  • Spárujte návratový typ s typy parametrů pro operátory krátkých spojů (& a |), které pracují s uživatelskými typy (CS0217).
  • Implementujte oba prvky operator true a operator false při použití vlastních typů v boolovských kontextech, jako jsou &&, a || (CS0218).

Následující příklad ukazuje chyby logického operátoru:

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
    }
}

Kontrolované operátory

  • CS9023: Operátor nelze nastavit jako ověřovaný
  • CS9024: Operátor nelze nastavit jako neověřený
  • CS9025: Kontrolovaný operátor vyžaduje, aby byla deklarována také odpovídající nekontrolovaná verze.

Chcete-li správně používat kontrolované operátory, postupujte podle těchto požadavků. Další informace naleznete v tématu Aritmetické operátory a uživatelem definované kontrolované operátory.

  • Použití checked nebo unchecked klíčových slov pouze u podporovaných aritmetických operátorů: +, -, *, /, ++, , --a explicitních převodů (CS9023, CS9024).
  • Při deklarování kontrolovaného operátoru (CS9025) zadejte zaškrtnuté i nezaškrtnuté verze. Kompilátor potřebuje, aby zpracovával různé kontexty.

Požadavky na rozhraní a dědičnost

  • CS9311: Typ neimplementuje člena rozhraní. Typ nemůže implementovat člena, protože jeden z nich není operátor.
  • CS9312: Typ nemůže přepsat zděděný člen, protože jeden z nich není definován jako operátor
  • CS9313: Přetížený operátor složeného přiřazení přebírá jeden parametr

Pokud chcete správně implementovat a přepsat operátory, postupujte podle těchto požadavků. Další informace naleznete v tématu Přetížení operátoru a rozhraní.

  • Ujistěte se, že deklarace operátorů odpovídají podpisu a typu členů rozhraní (CS9311). Operátor nemůže implementovat člena, který není operátorem.
  • Ověřte, že zděděné členy, které přepisujete, jsou také operátory (CS9312). Operátor nemůže přepsat člena, který není operátorem.
  • Deklarujte operátory složeného přiřazení jedním parametrem (CS9313). Levý operand je implicitně this.

Operátory rovnosti

  • CS0660: Typ definuje operátor == nebo operátor !=, ale nepřepíše Object.Equals(object o)
  • CS0661: Typ definuje operátor == nebo operátor !=, ale nepřepisuje Object.GetHashCode()

Chcete-li implementovat rovnost správně, přepište odpovídající Object metody při definování vlastních operátorů rovnosti. Další informace naleznete v tématu Definování rovnosti hodnot pro typ a operátory rovnosti.

  • Přepište Object.Equals, když definujete operator == nebo operator != (CS0660).
  • Přepište Object.GetHashCode, když definujete operator == nebo operator != (CS0661).

Přepsání těchto metod zajišťuje konzistentní kontrolu rovnosti napříč různými API a typy kolekcí.