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 inskrivna 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 kan bara 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
  • 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
  • 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 "RequiresUnsafe" eller "extern"
  • 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 "RequiresUnsafe" eller "extern" 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.

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). Flerdimensionell indexering stöds inte vid pekare.
  • 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

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).

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 inskrivna lokala variabler kan inte åtgärdas
  • CS1656: Det går inte att tilldela till variabeln eftersom den är en skrivskyddad variabeltyp

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).

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 "RequiresUnsafe" eller "extern"
  • 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 "RequiresUnsafe" eller "extern" för att uppfylla villkoret "new()" för typparametern "type parameter" i "generisk typ eller metod"

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.
  • Håll osäker kod separat från asynkron kod (CS4004). Kompilatorn tillåter inte await uttryck i ett unsafe block eftersom körmiljön inte kan garantera pekarens giltighet mellan pauspunkter. Skapa separata metoder för osäkra åtgärder och anropa dem från asynkrona metoder.
  • 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 som markerats med RequiresUnsafe eller extern (CS9362) eller medlemmar med pekare i sina signaturer (CS9363). C# 15-kompilatorn spårar osäker medlemsanvändning på anropsplatsen, inte bara vid deklarationen.
  • Använd en unsafe kontext när en new() begränsning kräver att en konstruktor anropas markerad med RequiresUnsafe eller extern (CS9376). Den allmänna instansieringen anropar konstruktorn implicit, så den anropande kontexten måste vara osäker.

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.

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.

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
  • 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 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).
  • 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.