Lösa fel och varningar i osäkra kodkonstruktioner

Den här artikeln beskriver följande diagnostik för kompilatorn:

  • CS0193: Operatorn * eller -> måste tillämpas på en pekare
  • CS0196: En pekare måste indexeras med endast ett värde
  • CS0208: Det går inte att ta adressen till, hämta storleken på eller deklarera en pekare till en hanterad typ ("typ")
  • CS0209: Typen av lokal som deklareras i en fixed -instruktion måste vara en pekartyp
  • CS0210: Du måste ange en initierare i en fixed - eller using -instruktionsdeklaration
  • CS0211: Det går inte att ta adressen till det angivna uttrycket
  • CS0212: Du kan bara ta adressen till ett ofixerat uttryck i en fixed instruktionsinitiator
  • CS0213: Du kan inte använda -instruktionen fixed för att ta adressen till ett redan fast uttryck
  • CS0214: Pekare och buffertar med fast storlek kan endast användas i en osäker kontext
  • CS0227: Osäker kod kan bara visas om den kompileras med /unsafe
  • CS0233: "identifierare" har ingen fördefinierad storlek, därför kan storleken endast användas i en osäker kontext
  • CS0242: Åtgärden i fråga är odefinierad vid tomrumspekare
  • CS0244: Varken 'is' eller 'as' är giltig på pekartyper
  • CS0254: Den högra sidan av en fast instruktionstilldelning kanske inte är ett cast-uttryck
  • CS0459: Det går inte att ta adressen till en skrivskyddad lokal variabel
  • CS0821: Implicit skrivna lokala variabler kan inte åtgärdas
  • CS1641: Ett buffertfält med fast storlek måste ha matrisstorleksspecificeraren efter fältnamnet
  • CS1642: Buffertfält med fast storlek får endast vara medlemmar i structs
  • CS1656: Det går inte att tilldela till 'variabel' eftersom det är en 'skrivskyddad variabel'
  • CS1663: Bufferttypen fast storlek måste vara något av följande: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong eller float, double
  • CS1664: Bufferten för fast storlek med längden "längd" och typen "typ" är för stor
  • CS1665: Buffertar med fast storlek måste ha en längd som är större än noll
  • CS1666: Du kan inte använda buffertar med fast storlek som finns i oberättade uttryck. Prova att använda den fasta instruktionen.
  • CS1708: Buffertar med fast storlek kan endast nås via lokala variabler eller fältvariabler
  • CS1716: Använd inte attributet .System.Runtime.CompilerServices.FixedBuffer Använd den fasta fältmodifieraren i stället.
  • CS1919: Osäker typ av "typnamn" kan inte användas vid skapande av objekt
  • CS4004: Det går inte await att i en osäker kontext
  • CS7092: En fast buffert kanske bara har en dimension.
  • CS8372: Använd inte attributet "System.Runtime.CompilerServices.FixedBuffer" på en egenskap
  • CS8385: Det angivna uttrycket kan inte användas i en fast instruktion
  • CS8500: Detta tar adressen till, hämtar storleken på eller deklarerar en pekare till en hanterad typ ("typ")
  • CS8812: Det går inte att konvertera &metodgruppen "metod" till icke-funktionspekartypen "typ".
  • CS9049: Ett fast fält får inte vara ett referensfält.
  • CS9123: Operatorn '&' ska inte användas på parametrar eller lokala variabler i asynkrona metoder.
  • CS9360: Den här åtgärden kan endast användas i en osäker kontext
  • CS9361: stackalloc uttryck utan initiering SkipLocalsInit kan endast användas i en osäker kontext
  • CS9362: "medlem" måste användas i en osäker kontext eftersom den är markerad som "unsafe"
  • CS9363: "medlem" måste användas i en osäker kontext eftersom den har pekare i sin signatur
  • CS9364: Osäker medlem "medlem" kan inte åsidosätta säker medlem "medlem"
  • CS9365: Osäker komponent "medlem" kan inte på ett implicit sätt implementera säker komponent "medlem"
  • CS9366: Osäker medlem "medlem" kan inte implementera säker medlem "medlem"
  • CS9367: RequiresUnsafeAttribute kan inte tillämpas på den här symbolen.
  • CS9368: RequiresUnsafeAttribute är endast giltigt enligt de uppdaterade reglerna för minnessäkerhet.
  • CS9376: En osäker kontext krävs för konstruktorn "konstruktor" markerad som "unsafe" för att uppfylla villkoret "new()" för typparametern "type parameter" i "generisk typ eller metod"
  • CS9377: Modifieraren harunsafe ingen effekt här enligt de aktuella säkerhetsreglerna för minne.
  • CS9379: Använd inte "RequiresUnsafeAttribute" i källan, använd modifieraren iunsafe stället.
  • CS9388: Modifieraren 'safe' får endast användas på 'extern'-medlemmar som inte har markerats med 'unsafe'.
  • CS9389: "extern" medlem måste vara märkt "unsafe" eller "safe".
  • CS9390: Båda de partiella medlemsdeklarationerna måste vara märkta "safe" eller så kan ingen av dem markeras "safe"
  • CS9392: Fältet i en explicit eller utökad layouttyp måste vara märkt "unsafe" eller "safe".
  • CS9396: Det går inte att ange modifierarna 'unsafe' eller 'safe' för både egenskapen eller indexeraren 'property' och dess accessor. Ta bort en av dem.
  • CS9397: Det går inte att ange samma modifierare 'unsafe' eller 'safe' för alla åtkomstfunktioner i egenskapen eller indexeraren 'property'. Placera i stället modifieraren på själva egenskapen.
  • CS9398: Det går inte att använda await i kontexten för en 'fixed'-sats

Pekaroperationer och dereferensering

  • CS0193: Operatorn * eller -> måste tillämpas på en pekare
  • CS0196: En pekare måste indexeras med endast ett värde
  • CS0242: Åtgärden i fråga är odefinierad vid tomrumspekare

Om du vill använda pekaråtgärder korrekt följer du reglerna för dereferencing, indexering och aritmetiska åtgärder. Mer information finns i Pekartyper och funktionspekare.

  • Använd operatorn * eller -> endast på datapekare (CS0193). Använd inte dessa operatorer med icke-pointer-typer eller funktionspekare. Till skillnad från i C/C++ kan du inte avreferera funktionspekare i C#.
  • Indexpekare med endast ett värde (CS0196). Pekare stöder inte flerdimensionell indexering.
  • Undvik åtgärder som är odefinierade vid tomrumspekare (CS0242). Öka till exempel inte en tomrumspekare eftersom kompilatorn inte vet storleken på de data som pekas på.

Pekartyper och hanterade typer

  • CS0208: Det går inte att ta adressen till, hämta storleken på eller deklarera en pekare till en hanterad typ ("typ")
  • CS0233: "identifierare" har ingen fördefinierad storlek, därför kan storleken endast användas i en osäker kontext
  • CS8500: Detta tar adressen till, hämtar storleken på eller deklarerar en pekare till en hanterad typ ("typ")

Om du vill arbeta med pekare och operatorn sizeof korrekt använder du ohanterade typer och rätt kontexter. Mer information finns i Ohanterade typer och operatornsizeof.

  • Använd endast pekare med ohanterade typer (CS0208). Ta inte adressen till, beräkna storleken på eller deklarera pekare till hanterade typer. Hanterade typer inkluderar referenstyper och structs som innehåller fält eller egenskaper för referenstyp.
  • Använd operatorn sizeof i en unsafe kontext när du arbetar med typer vars storlek inte är en kompileringskonstant (CS0233).
  • Undvik att ta adressen till, hämta storleken på eller deklarera en pekare till en hanterad typ (CS8500). Den här varningen (nivå 4) utlöses när kompilatorn identifierar pekaråtgärder på hanterade typer. En hanterad typ är en referenstyp eller en struct som innehåller en referenstyp som ett fält eller en egenskap. Mer information finns i Ohanterade typer.

Användning av fastställd sats

  • CS0209: Typen av lokal som deklareras i en fast instruktion måste vara en pekartyp
  • CS0210: Du måste ange en initierare i en fast eller using satsdeklaration
  • CS0211: Det går inte att ta adressen till det angivna uttrycket
  • CS0212: Du kan bara ta adressen till ett ofixerat uttryck i en initiator för fast instruktion
  • CS0213: Du kan inte använda den fasta instruktionen för att ta adressen till ett redan fast uttryck
  • CS0254: Den högra sidan av en fast instruktionstilldelning kanske inte är ett cast-uttryck
  • CS0459: Det går inte att ta adressen till en skrivskyddad lokal variabel
  • CS0821: Implicit skrivna lokala variabler kan inte åtgärdas
  • CS1656: Det går inte att tilldela till variabeln eftersom den är en skrivskyddad variabeltyp
  • CS8385: Det angivna uttrycket kan inte användas i en fast instruktion

Dessa fel uppstår när du använder -instruktionenfixed felaktigt. Instruktionen fixed hindrar skräpinsamlaren från att flytta en flyttbar variabel och deklarerar en pekare till variabeln. Mer information finns i Osäker kod och pekare.

Så här använder du instruktionen fixed korrekt:

  • Deklarera variabeln som en pekartyp (CS0209).
  • Ange en initierare i deklarationen av fixed-satsen (CS0210).
  • Ta endast adressen till giltiga uttryck: fält, lokala variabler och indirekt pekare (CS0211). Ta inte adressen av beräknade uttryck som summan av två variabler.
  • Använd adressoperatorn endast för ofixerade uttryck inom satssinitialiserare fixed (CS0212).
  • Använd inte en fixed instruktion för redan fasta uttryck (CS0213). Lokala variabler och parametrar i en unsafe metod är redan fasta i stacken.
  • Använd inte cast-uttryck till höger i en fixed instruktionstilldelning (CS0254).
  • Ta inte adressen till skrivskyddade lokala variabler (CS0459). Variabler i foreach loopar, using satser och fixed satser är skrivskyddade. Det här felet genereras inte längre av aktuella versioner av kompilatorn.
  • Använd explicita typer i stället för var i fixed -instruktioner (CS0821).
  • Tilldela inte variabler i kontexter som endast kan läsas, som foreach loopar, using uttryck eller fixed uttryck (CS1656).
  • Använd endast uttryck som stöder fixering i en fixed-instruktion (CS8385). Uttrycket måste vara en adresserbar variabel, en sträng eller en typ som implementerar en lämplig GetPinnableReference metod.

Krav på osäker kontext

  • CS0214: Pekare och buffertar med fast storlek kan endast användas i en osäker kontext
  • CS0227: Osäker kod kan bara visas om kompilering med /osäker
  • CS0244: Varken 'is' eller 'as' är giltig på pekartyper
  • CS1919: Osäker typ av "typnamn" kan inte användas vid skapande av objekt
  • CS4004: Det går inte att använda await i en osäker kontext
  • CS9123: Operatorn "&" ska inte användas för parametrar eller lokala variabler i asynkrona metoder
  • CS9360: Den här åtgärden kan endast användas i en osäker kontext
  • CS9361: stackalloc uttryck utan initiering SkipLocalsInit kan endast användas i en osäker kontext
  • CS9362: "medlem" måste användas i en osäker kontext eftersom den är markerad som "unsafe"
  • CS9363: "medlem" måste användas i en osäker kontext eftersom den har pekare i sin signatur
  • CS9376: En osäker kontext krävs för konstruktorn "konstruktor" markerad som "unsafe" för att uppfylla villkoret "new()" för typparametern "type parameter" i "generisk typ eller metod"
  • CS9398: Det går inte att använda await i kontexten av en "fixed"-sats

Den här diagnostiken inträffar när du använder osäkra kodkonstruktioner utan nödvändig unsafe kontext, eller när du försöker utföra åtgärder som inte tillåts med osäkra typer. Mer information finns i Osäker kod och pekare och nyckelordetunsafe.

  • Markera metoder, typer eller kodblock som använder pekare eller buffertar med fast storlek med nyckelordet unsafe (CS0214). Kompilatorn kräver en explicit osäker kontext för all kod som fungerar med pekartyper eller buffertfält med fast storlek.
  • Aktivera kompileringsalternativet AllowUnsafeBlocks i projektinställningarna (CS0227). Utan det här alternativet avvisar kompilatorn alla unsafe block även om koden annars är korrekt.
  • Använd inte operatorerna is eller as med pekartyper (CS0244). Dessa typtestoperatorer är inte giltiga för pekare eftersom pekare inte deltar i typhierarkin.
  • Använd inte operatorn new för att skapa pekartypsinstanser (CS1919). Om du vill skapa objekt i ohanterat minne använder du interop för att anropa interna metoder som returnerar pekare.
  • Behandla CS4004 som äldre vägledning. I C# 14 och tidigare await är det inte tillåtet i en osäker kontext. I C# 15-förhandsversionen av minnessäkerhetsändringar await tillåts i ett osäkert sammanhang, så den här allmänna begränsningen beskriver inte längre den aktuella regeln.
  • Använd inte operatorns adress (&) för parametrar eller lokala variabler i asynkrona metoder (CS9123). Variabeln kanske inte finns i stacken när den asynkrona operationen återupptas efter en pauspunkt.
  • Markera åtgärder som omfattar osäkra konstruktioner (till exempel pekaravreferering, adress för eller sizeof på ohanterade typer) med nyckelordet unsafe (CS9360). Enligt C# 15:s uppdaterade minnessäkerhetsregler identifierar kompilatorn enskilda åtgärder som kräver en osäker kontext.
  • Använd nyckelordet unsafe för stackalloc uttryck utan initialiserare när SkipLocalsInit attributet används (CS9361). Utan initialiserare innehåller det stackallokerade minnet onitialiserade data, vilket är en osäker åtgärd.
  • Använd en unsafe kontext när du anropar medlemmar markerade unsafe (CS9362) eller medlemmar med pekare i sina signaturer (CS9363). Enligt den uppdaterade minnessäkerhetsmodellen rapporterar kompilatorn CS9362 för medlemmar som uttryckligen sprider säkerhetsskyldigheten till anroparen och CS9363 för äldre kompatibilitetsfall där själva signaturen innehåller pekare.
  • Använd en unsafe kontext när en new() begränsning kräver att en konstruktor anropas markerad unsafe (CS9376). Den allmänna instansieringen anropar konstruktorn implicit, så den anropande kontexten måste vara osäker.
  • Flytta await utanför brödtexten eller initieraren för en fixed -instruktion (CS9398). C# 15-förhandsversionen tillåter await i ett osäkert sammanhang, men pinning-livslängden för en fixed-sats kan fortfarande inte sträcka sig över en asynkron suspensionspunkt. Vänta på operationen innan du går in i fixed, eller avsluta satsen fixed innan du använder await.

Osäkra säkerhetsavtal för medlemmar

  • CS9364: Osäker medlem "medlem" kan inte åsidosätta säker medlem "medlem"
  • CS9365: Osäker medlem 'medlem' kan inte implicit implementera säker medlem 'medlem'
  • CS9366: Osäker medlem "medlem" kan inte implementera säker medlem "medlem"
  • CS9367: RequiresUnsafeAttribute kan inte tillämpas på den här symbolen.
  • CS9368: RequiresUnsafeAttribute är endast giltigt enligt de uppdaterade reglerna för minnessäkerhet.
  • CS9377: Modifieraren harunsafe ingen effekt här enligt de aktuella säkerhetsreglerna för minne.
  • CS9379: Använd inte "RequiresUnsafeAttribute" i källan, använd modifieraren iunsafe stället.
  • CS9388: Modifieraren 'safe' får endast användas på 'extern'-medlemmar som inte är markerade med 'unsafe'.
  • CS9389: "extern" medlem måste vara märkt "unsafe" eller "safe".
  • CS9390: Båda de partiella medlemsdeklarationerna måste vara märkta "safe" eller så kan ingen av dem markeras "safe"
  • CS9396: Det går inte att ange modifierarna 'unsafe' eller 'safe' på både egenskapen eller indexeraren 'property' och dess accessor. Ta bort en av dem.
  • CS9397: Det går inte att ange samma modifierare 'unsafe' eller 'safe' för alla åtkomstorer i egenskapen eller indexeraren 'property'. Placera i stället modifieraren på själva egenskapen.

Den här diagnostiken tillämpar C# 15 säkerhetsavtalsregler för medlemmar som har markerats som osäkra. Kompilatorn ser till att osäkra medlemmar inte bryter mot de säkerhetsförväntningar som fastställts av basklasser och gränssnitt. Mer information finns i Osäker kod och pekare och nyckelordetunsafe.

  • Åsidosätt inte en säker basmedlem med en osäker medlem (CS9364). En överskrivning måste upprätthålla säkerhetskontraktet för basmedlemmen. Om basmedlemmen är säker måste åsidosättningen också vara säker. unsafe Ta bort modifieraren eller RequiresUnsafeAttribute från den överordnade medlemmen eller markera basmedlemmen som osäker.
  • Implementera inte implicit en säker gränssnittsmedlem med en osäker medlem (CS9365). När en typ implicit implementerar en gränssnittsmedlem förväntar sig anropare via gränssnittet en säker åtgärd. Ta bort den osäkra beteckningen från implementeringsmedlemmen eller använd explicit gränssnittsimplementering.
  • Implementera inte uttryckligen en säker gränssnittsmedlem med en osäker medlem (CS9366). Även med explicit implementering måste gränssnittsmedlemmens säkerhetsavtal bevaras.
  • Gäller RequiresUnsafeAttribute endast för symboltyper som stöds (CS9367). Det här attributet kan tillämpas på metoder, egenskaper, händelser, konstruktorer och typer, men inte alla symboltyper stöder det.
  • Aktivera de uppdaterade minnessäkerhetsreglerna att använda RequiresUnsafeAttribute (CS9368). Det här attributet är en del av C# 15:s förfinade minnessäkerhetsmodell och känns inte igen enligt äldre regler. Se till att projektet riktar in sig på en språkversion som stöder de uppdaterade reglerna.
  • unsafe Ta bort modifieraren när den inte har någon effekt (CS9377). Enligt de aktuella minnessäkerhetsreglerna kräver eller drar vissa kontexter inte nytta av unsafe modifieraren. Kompilatorn varnar när modifieraren är meningslös så att du kan rensa onödiga anteckningar.
  • unsafe Använd modifieraren direkt i medlemsdeklarationen i stället för att använda RequiresUnsafeAttribute i källan (CS9379). Attributet är endast avsett för metadatarepresentation. i källkoden är nyckelordet unsafe rätt mekanism.
  • Använd modifieraren safe endast för extern-medlemmar som inte redan är markerade med unsafe (CS9388). Modifieraren safe väljer uttryckligen en extern medlem från det osäkra standardantagandet för externa deklarationer.
  • Markera varje extern medlem som antingen unsafe eller safe (CS9389). Enligt de uppdaterade minnessäkerhetsreglerna måste externa medlemmar uttryckligen deklarera sitt säkerhetskontrakt eftersom kompilatorn inte kan verifiera implementeringen.
  • Se till att båda de partiella medlemsdeklarationerna är överens om safe modifieraren (CS9390). Om en partiell deklaration är markerad safe, måste den andra också markeras safe för att bibehålla ett konsekvent säkerhetskontrakt.
  • Placera unsafe eller safe på antingen egenskapen eller indexeraren, eller på en accessor, men inte båda (CS9396). Om egenskapen fastställer kontraktet för alla åtkomstmetoder, placerar du modifieraren på själva egenskapen. Om endast en accessor skiljer sig åt placerar du modifieraren på den accessorn och lämnar egenskapen oförändrad.
  • Om varje användare av en egenskap eller indexerare skulle ha samma unsafe eller safe modifierare flyttar du den modifieraren till egenskapen eller indexerarens deklaration (CS9397). Använd endast åtkomstmodifierare när åtkomstgivarna avsiktligt skiljer sig åt.

Uttryckliga eller utökade layoutfält

  • CS9392: Fältet i en explicit eller utökad layouttyp måste vara märkt "unsafe" eller "safe".

Den här diagnostiken sker under den uppdaterade minnessäkerhetsmodellen när ett instansfält deltar i explicit eller utökad layout och deklarationen inte anger om fältet är unsafe eller safe. Mer information finns i Osäker kod och pekare och nyckelordetsafe.

  • Markera varje instansfält i en typ med [StructLayout(LayoutKind.Explicit)] eller [ExtendedLayout] som antingen unsafe eller safe (CS9392). Om fältet syntetiseras för en autoegenskap, fältstödd egenskap, primär konstruktorparameter eller fältliknande händelse placerar du modifieraren på egenskapen, parametern eller händelsen som äger det genererade fältet.

Buffertar med fast storlek

  • CS1641: Ett buffertfält med fast storlek måste ha matrisstorleksspecificeraren efter fältnamnet
  • CS1642: Buffertfält med fast storlek får endast vara medlemmar i structs
  • CS1663: Bufferttypen fast storlek måste vara något av följande: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong eller float, double
  • CS1664: Bufferten för fast storlek med längden "längd" och typen "typ" är för stor
  • CS1665: Buffertar med fast storlek måste ha en längd som är större än noll
  • CS1666: Du kan inte använda buffertar med fast storlek som ingår i ofixerade uttryck. Prova att använda fixed-satsen.
  • CS1708: Buffertar med fast storlek kan endast nås via lokala variabler eller fältvariabler
  • CS1716: Använd inte attributet .System.Runtime.CompilerServices.FixedBuffer Använd den fasta fältmodifieraren i stället.
  • CS7092: En fast buffert kanske bara har en dimension.
  • CS8372: Använd inte attributet "System.Runtime.CompilerServices.FixedBuffer" på en egenskap
  • CS9049: Ett fast fält får inte vara ett referensfält.

Dessa fel uppstår när du arbetar med buffertar med fast storlek. Buffertar med fast storlek är matriser som bäddas in direkt i structs och används främst för interop-scenarier. Mer information finns i Buffertar med fast storlek.

Så här deklarerar och använder du buffertar med fast storlek på rätt sätt:

  • Ange matrisstorleken efter fältnamnet med hjälp av en positiv heltalskonstant (CS1641, CS1665). Buffertens totala storlek (elementantal multiplicerat med elementstorlek) får inte överstiga 2^31 byte (CS1664).
  • Deklarera buffertar med fast storlek endast i structs, inte i klasser (CS1642). Använd en vanlig matris om du behöver fältet i en klass.
  • Använd någon av de elementtyper som stöds: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, floateller double (CS1663).
  • Använd en fixed instruktion för att fästa den innehållande structen innan du kommer åt bufferten (CS1666).
  • Få åtkomst till buffertar med fast storlek endast via lokala variabler eller fält, inte via mellanliggande uttryck (CS1708).
  • fixed Använd fältmodifieraren i stället för System.Runtime.CompilerServices.FixedBuffer attributet (CS1716). Använd inte det här attributet på egenskaper heller (CS8372).
  • Deklarera fasta buffertar med endast en dimension (CS7092). Flerdimensionella fasta buffertar stöds inte.
  • Deklarera inte buffertar med fast storlek som ref fält (CS9049). Buffertar med fast storlek måste vara värdefält.

Funktionspekare

  • CS8812: Det går inte att konvertera &metodgruppen "metod" till icke-funktionspekartypen "typ".

Om du vill hämta en funktionspekare använder du operatorns adress med en explicit funktionspekartyp. Använd inte adressoperatorn & för att tilldela metodgrupper till void* eller andra typer av pekare som inte är funktioner. Mer information finns i Funktionspekare.