Dela via


Lösa fel och varningar för operatordeklarationer och överflöde

Den här artikeln beskriver följande kompilatorfel och varningar:

  • CS0031: Konstantvärdet "värde" kan inte konverteras till en "typ"
  • CS0056: Ojämn tillgänglighet: returtypen 'typ' är mindre tillgänglig än operatören 'operator'
  • CS0057: Inkonsekvent tillgänglighet: parametertypen "type" är mindre tillgänglig än operatorn operator
  • CS0215: Returtypen för operatorn True eller False måste vara bool
  • CS0216: Operatorn "operator" kräver att en matchande operator "missing_operator" också definieras
  • CS0217: För att kunna användas som kortslutningsoperator måste en användardefinierad logisk operator ('operator') ha samma returtyp som typen av dess 2 parametrar.
  • CS0218: Typen ("typ") måste innehålla deklarationer av operatorn true och operator false
  • CS0220: Åtgärden resulterar i ett spill vid kompilering i kontrollerat läge
  • CS0221: Konstantvärdet "värde" kan inte konverteras till en "typ" (använd "omarkerad" syntax för att åsidosätta)
  • CS0448: Returtypen för ++ eller -- operatorn måste vara den innehållande typen eller härledd från den innehållande typen
  • CS0463: Utvärderingen av decimalkonstantuttrycket misslyckades med felet: "error"
  • CS0543: "uppräkning" : uppräkningsvärdet är för stort för att få plats i dess typ
  • CS0552: "konverteringsrutin" : användardefinierad konvertering till/från gränssnitt
  • CS0553: "konverteringsrutin" : användardefinierad konvertering till/från basklass
  • CS0554: "konverteringsrutin" : användardefinierad konvertering till/från härledd klass
  • CS0555: Användardefinierad operator kan inte ta ett objekt av den omslutande typen och konvertera till ett objekt av den omslutande typen
  • CS0556: Användardefinierad konvertering måste konverteras till eller från den omslutande typen
  • CS0557: Duplicera användardefinierad konvertering i typ
  • CS0558: Användardefinierad operator måste deklareras som statisk och offentlig
  • CS0559: Parametertypen för ++ eller -- operatorn måste vara den innehållande typen
  • CS0562: Parametern för en unary-operator måste vara den innehållande typen
  • CS0563: En av parametrarna för en binär operator måste vara den innehållande typen
  • CS0564: Den första operand av en överbelastad skiftoperator måste ha samma typ som den innehållande typen, och typen av den andra operanden måste vara int
  • CS0567: Gränssnitt får inte innehålla operatorer
  • CS0590: Användardefinierade operatorer kan inte returnera void
  • CS0594: Flyttalskonstanten ligger utanför intervallet av typen "typ"
  • CS0652: Jämförelse med integrerad konstant är värdelös; konstanten ligger utanför intervallet av typen "typ"
  • CS0659: "klass" åsidosätter Object.Equals(object o) men åsidosätter inte Object.GetHashCode()
  • CS0660: Typen definierar operator == och operator != men åsidosätter inte Object.Equals(object o)
  • CS0661: Typ definierar operator == eller operator !=, men åsidosätter inte Object.GetHashCode()
  • CS0715: Statiska klasser får inte innehålla användardefinierade operatorer
  • CS1021: Integralkonstanten är för stor
  • CS1037: Överbelastningsbar operator förväntas
  • CS1553: Deklarationen är inte giltig. Använd "modifieraroperator <av typen> (..." istället
  • CS8930: Explicit implementering av en användardefinierad operator måste deklareras som statisk
  • CS8931: Användardefinierad konvertering i ett gränssnitt måste konverteras till eller från en typparameter på den omslutande typ som är begränsad till den omslutande typen
  • CS8778: Konstantvärdet "värde" kan överskrida "typ" under körning (använd syntaxen "unchecked" för att åsidosätta)
  • CS8973: Åtgärden kan överflöda vid körning (använd 'unchecked' syntax för att åsidosätta)
  • CS9023: Operatorn kan inte kontrolleras.
  • CS9024: Operatorn kan inte avmarkeras.
  • CS9025: Operatorn kräver att en matchande icke-kontrollerad version också deklareras.
  • CS9027: Oväntat nyckelord "avmarkerat".
  • CS9308: Användardefinierad operator måste deklareras som offentlig.
  • CS9310: Returtypen för den här operatorn måste vara ogiltig.
  • CS9311: Typen implementerar inte gränssnittsmedlem. Typen kan inte implementera medlem eftersom en av dem inte är en operator.
  • CS9312: Typen kan inte åsidosätta ärvd medlem eftersom en av dem inte är en operator.
  • CS9313: Överlagrad sammansatt tilldelningsoperator tar en parameter.
  • CS9340: Operatorn kan inte tillämpas på operander. Den närmaste oanvändbara kandidaten visas.
  • CS9341: Operatorn kan inte tillämpas på operand. Den närmaste oanvändbara kandidaten visas.
  • CS9342: Operatörsupplösningen är tvetydig mellan följande medlemmar.

Krav för operatorsignatur

  • CS0448: Returtypen för ++ eller -- operatorn måste vara den innehållande typen eller härledd från den innehållande typen.
  • CS0559: Parametertypen för ++ eller -- operatorn måste vara den innehållande typen.
  • CS0562: Parametern för en unary-operator måste vara den innehållande typen.
  • CS0563: En av parametrarna för en binär operator måste vara den innehållande typen.
  • CS0564: Den första operanden av en överlagd skiftoperator måste ha samma typ som den innehållande typen, och typen av den andra operanden måste vara int.
  • CS0567: Gränssnitt får inte innehålla operatorer.
  • CS0590: Användardefinierade operatorer kan inte returnera void.
  • CS9310: Returtypen för den här operatorn måste vara ogiltig.
  • CS9340: Operatorn kan inte tillämpas på operander. Den närmaste oanvändbara kandidaten visas.
  • CS9341: Operatorn kan inte tillämpas på operand. Den närmaste oanvändbara kandidaten visas.
  • CS9342: Operatorresolutionen är tvetydig mellan följande medlemmar.

Varje operatortyp har specifika krav för parameter och returtyp som definieras av språkspecifikationen. Fullständiga regler för vilka operatorer som kan överbelastas finns i Operatoröverlagring och Operatorer i C#-specifikationen.

  • Ändra returtypen för ++ eller ---operatorerna till den omgivande typen eller en typ som är härledd från den (CS0448). Språket kräver att operatorerna för ökning och minskning returnerar ett värde som är kompatibelt med den innehållande typen så att resultatet kan tilldelas tillbaka till samma variabel.
  • Ändra parametern för ++ eller ---operatorerna till den innehållande typen (CS0559). Inkrements- och minskningsoperatorer måste fungera på instanser av sin egen typ.
  • Ändra parametern för en unary-operator till den innehållande typen (CS0562). Unary-operatorer måste acceptera en operand av den typ som deklarerar dem.
  • Se till att minst en parameter för en binär operator är den innehållande typen (CS0563). Binära operatorer måste involvera den deklarerande typen så att kompilatorn kan lösa dem genom den typen.
  • Ändra den första parametern för en skiftoperator till den innehållande typen och den andra parametern till int (CS0564). Språket definierar skiftoperatorer med en specifik signatur: den typ som skiftas och en heltalsskiftmängd.
  • Flytta operatordeklarationer från gränssnitt och till klasser eller structs (CS0567). Traditionella (icke-statiska abstrakta) operatordeklarationer tillåts inte i gränssnitt. Statiska abstrakta operatorer i gränssnitt finns i Statiska abstrakta och virtuella gränssnittsmedlemsfel.
  • Ändra returtypen för operatorn till en icke-void-typ (CS0590). De flesta användardefinierade operatorer måste returnera ett värde. Undantaget är sammansatta tilldelningsoperatorer som kräver en void returtyp (CS9310).
  • Korrigera parametertyperna eller lägg till saknade operatoröverlagringar så att kompilatorn kan hitta en matchande operator för de operandtyper som används på anropsplatsen (CS9340, CS9341). När det inte finns någon tillämplig operator visar kompilatorn den närmaste kandidaten för att diagnostisera matchningsfelet.
  • Lägg till explicita typkonverteringar på anropsplatsen eller ge mer specifika överlagringar för att ta bort tvetydighet när flera överbelastningar för operatören matchar lika bra (CS9342).

Viktigt!

Signaturkraven för statiska binära operatorer och motsvarande instans sammansatta tilldelningsoperatorer skiljer sig åt. Kontrollera att signaturen matchar den deklaration du vill ha.

Krav för operatordeklaration

  • CS0558: Användardefinierad operator måste deklareras som statisk och offentlig.
  • CS0715: Statiska klasser får inte innehålla användardefinierade operatorer.
  • CS1037: Överbelastningsbar operator förväntas.
  • CS1553: Deklarationen är inte giltig. Använd "modifieraroperator <av typen> (..." istället.
  • CS9308: Användardefinierad operator måste deklareras som offentlig.

Språket kräver specifika modifierare och syntax för operatordeklarationer. Fullständiga regler finns i Operatoröverlagring och Användardefinierade konverteringsoperatorer.

  • Lägg till både static modifierare och public i operatordeklarationen (CS0558, CS9308). C#-språket kräver att alla användardefinierade operatorer är både statiska och offentliga så att de är tillgängliga och anropsbara utan en instans.
  • Flytta operatordeklarationen från en statisk klass till en icke-statisk klass eller struct (CS0715). Statiska klasser kan inte ha instanser, så användardefinierade operatorer – som körs på instanser av deras innehållande typ – är inte meningsfulla i statiska klasser.
  • Ersätt den ogiltiga operatorsymbolen med en giltig överlagringsbar operator (CS1037). Endast specifika operatorer som definieras av språket kan överbelastas.
  • Korrigera syntaxen så att den följer det obligatoriska formuläret för konverteringsoperator: public static implicit operator <dest-type>(<source-type> parameter) eller public static explicit operator <dest-type>(<source-type> parameter) (CS1553). Kompilatorn förväntar sig att konverteringsoperatorer följer ett specifikt deklarationsmönster.

Fel som rör explicita gränssnittsimplementeringar av operatorer i statiska abstrakta gränssnitt finns i Statiska abstrakta och virtuella gränssnittsmedlemsfel.

Inkonsekvent tillgänglighet

  • CS0056: Inkonsistent åtkomst: returtypen "typ" har mindre åtkomst än operatorn "operator".
  • CS0057: Inkonsekvent tillgänglighet: parametertypen 'type' är mindre tillgänglig än operatorn 'operator'.

Alla typer som används i en offentlig operators signatur måste vara minst lika tillgängliga som operatorn själv. Fullständiga regler finns i Åtkomstmodifierare och hjälpmedelsbegränsningar i C#-specifikationen.

  • Ändra returtypen till en typ som är minst lika tillgänglig som operatorn eller minska operatorns tillgänglighet så att den matchar returtypen (CS0056). En public-operator kan inte exponera en typ med lägre åtkomstnivå via sitt returvärde eftersom anropare utanför assemblyt inte skulle kunna använda resultatet.
  • Ändra parametertypen till en typ som är minst lika tillgänglig som operatorn, eller minska operatorns tillgänglighet så att den matchar parametertypen (CS0057). En public operator kan inte kräva en mindre tillgänglig typ som parameter eftersom anropare utanför sammansättningen inte skulle kunna ange argumentet.

Användardefinierade konverteringsbegränsningar

  • CS0552: Användardefinierad konvertering till/från-gränssnitt.
  • CS0553: Användardefinierad konvertering till/från basklass.
  • CS0554: Användardefinierad konvertering till/från härledd klass.
  • CS0555: Användardefinierad operator kan inte ta ett objekt av den omslutande typen och konvertera till ett objekt av den omslutande typen.
  • CS0556: Användardefinierad konvertering måste konverteras till eller från den omslutande typen.
  • CS0557: Duplicera användardefinierad konvertering i typ.

C#-språket begränsar vilka typer som kan delta i användardefinierade konverteringar. Fullständiga regler finns i Användardefinierade konverteringsoperatorer och Konverteringsoperatorer i C#-specifikationen.

  • Ta bort konverteringsoperatorn som konverteras till eller från en gränssnittstyp (CS0552). Språket förbjuder användardefinierade konverteringar med gränssnittstyper eftersom gränssnittskonverteringar hanteras via typsystemets referenskonverteringar och boxning. Använd explicita gränssnittsimplementeringar eller hjälpmetoder i stället.
  • Ta bort konverteringsoperatorn som konverterar till eller från en basklass (CS0553). Konverteringar mellan en typ och dess basklass finns redan via implicita referenskonverteringar (upcast) och explicita referenskonverteringar (nedcast), så en användardefinierad konvertering skulle skapa tvetydighet.
  • Ta bort konverteringsoperatorn som konverterar till eller från en härledd klass (CS0554). Precis som basklasskonverteringar är konverteringar mellan en typ och dess härledda typer inbyggda i språket genom arv, och användardefinierade konverteringar skulle hamna i konflikt med dem.
  • Ta bort konverteringsoperatorn som konverterar omslutningstypen till sig själv (CS0555). Varje typ har redan en implicit identitetskonvertering till sig själv, så en användardefinierad konvertering från en typ till samma typ är redundant och tillåts inte.
  • Ändra en av typerna i konverteringsoperatorn så att antingen käll- eller måltypen är den omslutande typen (CS0556). En användardefinierad konvertering måste omfatta den typ som deklarerar den– du kan inte definiera en konvertering mellan två orelaterade externa typer i en tredje typ.
  • Ta bort dubblettkonverteringsoperatorn eller ändra en av de duplicerade operatorerna så att käll- och måltyperna skiljer sig från den andra (CS0557). En typ kan endast deklarera en implicit och en explicit konvertering för ett givet par av käll- och måltyper.

Booleska operatorer och kortslutningsoperatorer

  • CS0215: Returtypen för operatorn true eller false måste vara bool.
  • CS0216: Operatorn kräver att en matchande operator också definieras.
  • CS0217: För att kunna användas som kortslutningsoperator måste en användardefinierad logisk operator ha samma returtyp som typen av dess 2 parametrar.
  • CS0218: Typen måste innehålla deklarationer av operatorn true och operator false.

C#-språket kräver specifika parkopplingar och signaturer för booleska operatorer och kortslutningsutvärdering. Fullständiga regler finns i sant och falskt operatorer, booleska logiska operatorer och användardefinierade villkorsstyrda logiska operatorer i C#-specifikationen.

  • Ändra returtypen för operator true och operator false till bool (CS0215). Dessa operatorer avgör om ett värde är logiskt sant eller falskt, så språket kräver att de returnerar bool.
  • Definiera den matchande parkopplade operatorn (CS0216). Språket kräver att vissa operatorer deklareras i par: operator == med operator !=, operator < med operator >, operator <= med operator >=och operator true med operator false.
  • Ändra returtypen för den användardefinierade & operatorn eller | operatorn så att den matchar båda parametertyperna (CS0217). För kortslutningsutvärdering (&& och ||), kräver kompilatorn att returntypen för &- eller |-operatorn, båda parametertyperna och den innehållande typen alla ska vara samma typ.
  • Lägg till både operator true och operator false deklarationer till typen (CS0218). Kompilatorn skriver om && och || och använder operator true, operator false och den motsvarande & eller |-operatören, så alla tre måste finnas för att kortslutningsutvärderingen ska kunna fungera.

Kontrollerade operatorer

  • CS9023: Operatorn kan inte kontrolleras
  • CS9024: Operatorn kan inte avmarkeras
  • CS9025: Kontrollerad operator kräver att en motsvarande okontrollerad version också deklareras
  • CS9027: Oväntat nyckelord "avmarkerat"

Nyckelorden checked och unchecked kan endast tillämpas på specifika operatordeklarationer. Fullständiga regler finns i Aritmetiska operatorer och Användardefinierade kontrollerade operatorer.

  • Ta bort nyckelordet checked eller unchecked från en operator som inte stöds (CS9023, CS9024). Endast de aritmetiska operatorerna +, -, *, /, ++, --och explicita konverteringsoperatorer stöder kontrollerade och avmarkerade varianter. Andra operatorer, till exempel jämförelse- eller jämlikhetsoperatorer, har inte ett distinkt överflödesbeteende och kan inte markeras som kontrollerade eller okontrollerade.
  • Lägg till en matchande okontrollerad version av operatorn (CS9025). En checked operator tillhandahåller beteendet för överflödeshantering, men kompilatorn behöver även motsvarande ej kontrollerad version för att kunna användas i unchecked kontexter och som standard när ingen kontext anges.
  • Ta bort nyckelordet unchecked från den ogiltiga positionen (CS9027). Nyckelordet unchecked i en operatordeklaration är endast giltigt som en del av operatorsyntaxen (till exempel public static explicit operator unchecked int(MyType t)). Om du placerar den någon annanstans i deklarationen uppstår ett syntaxfel.

Gränssnitts- och arvskrav

  • CS9311: Typen implementerar inte gränssnittsmedlem. Typen kan inte implementera medlem eftersom en av dem inte är en operator
  • CS9312: Typen kan inte åsidosätta ärvd medlem eftersom en av dem inte är en operator
  • CS9313: Överlagrad sammansatt tilldelningsoperator tar en parameter

Kompilatorn tillämpar strikt matchning mellan operatordeklarationer och gränssnittsmedlemmar eller basklassmedlemmar som de implementerar eller åsidosätter. Fullständiga regler finns i Överlagring av operatorer och gränssnitt.

  • Ändra implementeringsmedlemmen till en operatordeklaration som matchar gränssnittets operatörsmedlem eller ändra gränssnittsmedlemmen till en metod om implementeringsmedlemmen är en metod (CS9311). En operatör kan bara implementera en gränssnittsmedlem som också deklareras som en operatör – du kan inte uppfylla ett operatörskontrakt med en vanlig metod eller vice versa.
  • Ändra den överordnade medlemmen till en operatordeklaration som matchar basklassens operatörsmedlem eller ändra basklassmedlemmen till en metod om den härledda klassmedlemmen är en metod (CS9312). Precis som gränssnittsimplementering måste en åsidosättning matcha den typ av medlem som åsidosätts – en operatör kan inte åsidosätta en icke-operatörsmedlem.
  • Ändra deklarationen för sammansatt tilldelningsoperator så att den accepterar exakt en parameter (CS9313). Sammansatta tilldelningsoperatorer är instansmedlemmar där den vänstra operanden är implicit this, så endast den högra operanden deklareras som en parameter.

Likhetsoperatorer

  • CS0659: "klass" åsidosätter Object.Equals(object o) men åsidosätter inte Object.GetHashCode()
  • CS0660: Typ definierar operatorn == eller operatorn != men åsidosätter inte Object.Equals(object o)
  • CS0661: Typ definierar operatorn == eller operatorn != men åsidosätter inte Object.GetHashCode()

Kompilatorn kräver att likhetsrelaterade åsidosättningar och operatordefinitioner förblir synkroniserade. När du åsidosätter Object.Equals eller definierar operator == / operator !=måste du även ange de relaterade åsidosättningarna. Fullständiga regler finns i Definiera värdejämlikhet för en typ och likhetsoperatorer.

  • Lägg till en åsidosättning av Object.GetHashCode när du åsidosätter Object.Equals (CS0659). Hash-baserade samlingar som Dictionary<TKey,TValue> och HashSet<T> förlitar sig på kontraktet att två objekt som är lika med måste returnera samma hash-kod. Utan en motsvarande GetHashCode åsidosättning kan objekt som jämförs som lika hashas till olika segment, vilket kan leda till att uppslag och deduplicering misslyckas utan meddelande.
  • Lägg till en åsidosättning av Object.Equals när du definierar operator == eller operator != (CS0660). Kod som anropar Equals direkt – inklusive många ramverks-API:er, LINQ-metoder och insamlingsåtgärder – använder inte din anpassade operator. Utan en konsekvent Equals åsidosättning kan samma två objekt betraktas som lika av == men inte av Equals, vilket leder till oförutsägbart beteende.
  • Lägg till en åsidosättning av Object.GetHashCode när du definierar operator == eller operator != (CS0661). Precis som CS0659 måste GetHashCode du vara konsekvent med din likhetssemantik. Om operator == två objekt anses vara lika med men de returnerar olika hash-koder fungerar inte hash-baserade samlingar korrekt.

Överflödes- och underflödesfel

  • CS0031: Konstantvärdet "värde" kan inte konverteras till en "typ"
  • CS0220: Åtgärden flödar över vid kompileringstid i markerat läge
  • CS0221: Konstantvärdet "värde" kan inte konverteras till typen (använd "unchecked"-syntax för att åsidosätta)
  • CS0463: Utvärderingen av decimalkonstantuttrycket misslyckades med felet: "error"
  • CS0543: "uppräkning" : uppräkningsvärdet är för stort för att få plats i dess typ
  • CS0594: Flyttalskonstanten ligger utanför intervallet av typen "typ"
  • CS0652: Jämförelse med integrerad konstant är värdelös; konstanten ligger utanför intervallet av typen "typ"
  • CS1021: Integralkonstanten är för stor
  • CS8778: Konstantvärdet 'value' kan överskrida 'typ' vid körning (använd syntaxen 'unchecked' för att åsidosätta)
  • CS8973: Åtgärden kan flöda över vid körning (använd syntaxen "avmarkerad" för att åsidosätta)

Kompilatorn utvärderar konstanta uttryck vid kompileringstid och rapporterar fel eller varningar när ett värde överskrider det giltiga intervallet för dess måltyp. Fullständiga regler finns i kontrollerade och okontrollerade satser och heltalstyper.

  • Ändra konstantvärdet till ett som passar inom måltypens intervall eller ändra målet till en större numerisk typ (CS0031). Kompilatorn kan inte implicit begränsa en konstant som inte passar , till exempel att tilldela 256 till ett byte (intervall 0–255) genererar det här felet. Om trunkeringen är avsiktlig, använd en explicit typomvandling i en unchecked-kontext.
  • Korrigera aritmetiken i det konstanta uttrycket så att resultatet passar måltypen eller omslut uttrycket i en omarkerad kontext för att tillåta tyst spill (CS0220). Kompilatorn utvärderar hela konstantuttrycket vid kompileringstillfället i en markerad kontext som standard, så mellanliggande eller slutliga resultat som överskrider typens intervall orsakar det här felet.
  • Ändra konstantvärdet eller måltypen så att konverteringen är giltig eller omslut uttrycket i en unchecked kontext om du avsiktligt vill ha det trunkerade resultatet (CS0221). Till skillnad från CS0220 gäller det här felet explicita konstanta konverteringar där källvärdet inte passar måltypen.
  • Förenkla eller dela upp det konstanta decimal uttrycket så att det håller sig inom typområdet och precisionen decimal (CS0463). Typen decimal har ett maximalt värde på cirka \(7,9 \times 10^{28}\) och 28–29 signifikanta siffror, och kompilatorn utvärderar det fullständiga uttrycket vid kompileringstid.
  • Ändra uppräkningsmedlemsvärdet till ett värde som passar i uppräkningens underliggande typ eller ändra den underliggande typen till en större integraltyp (CS0543). Som standard används int som den underliggande typen för enumerationspaket. Om en medlems värde överskrider den underliggande typens intervall anger du en större typ som long.
  • Ändra flyttalskonstanten till ett värde inom måltypens intervall eller använd en typ med högre precision som double i stället för float (CS0594). Typen float stöder värden upp till cirka $3.4 \times 10^{38}$, och double stöder upp till cirka $1.7 \times 10^{308}$.
  • Ta bort eller korrigera jämförelsen så att konstanten ligger inom intervallet för variabelns typ (CS0652). Att jämföra en byte variabel med , till 300exempel, kan aldrig vara sant, så kompilatorn varnar för att jämförelsen är värdelös. Den här varningen anger ofta ett logikfel eller ett matchningsfel mellan variabeltypen och det avsedda intervallet med värden.
  • Använd en större numerisk typ eller dela upp värdet mellan flera åtgärder (CS1021). Det här felet uppstår när en heltalsliteral överskrider intervallet för även den största integraltypen (ulongupp till $1,8 \gånger 10^{19}$). Överväg att använda BigIntegerför värden utanför det intervallet.
  • Omslut uttrycket i en unchecked kontext för att utelämna varningen eller ändra värdet så att det passar inom måltypens intervall (CS8778). Den här varningen anger ett konstantomvandling som kan leda till dataförlust under körning—kompilatorn kan inte bevisa att ett överskott definitivt kommer att inträffa, men den identifierar risken.
  • Omslut uttrycket i en unchecked kontext för att förhindra varningen eller omstrukturera aritmetiken för att undvika potentiellt spill (CS8973). Den här varningen liknar CS8778 men gäller för aritmetiska åtgärder i stället för konverteringar – kompilatorn identifierar att åtgärden kan flöda över vid körning.