Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
| Eigenschap | Waarde |
|---|---|
| Regel-id | CA2020 |
| Titel | Gedragswijziging voorkomen die wordt veroorzaakt door ingebouwde operators van IntPtr/UIntPtr |
| Categorie | Betrouwbaarheid |
| Fix kan brekend of niet-brekend zijn | Niet-brekend |
| Standaard ingeschakeld in .NET 10 | Als suggestie |
| Toepasselijke talen | C# |
Oorzaak
Deze regel wordt geactiveerd wanneer een gedragswijziging tussen .NET 6 en .NET 7 wordt gedetecteerd die is geïntroduceerd door de nieuwe ingebouwde operators van IntPtr en UIntPtr.
Beschrijving van regel
Met de functie numerieke IntPtrIntPtr en UIntPtr ingebouwde operators voor conversies, unaire bewerkingen en binaire bewerkingen. Deze operators kunnen uitzonderingen opwerpen bij overloop in een gecontroleerde context of geen uitzonderingen opwerpen in een niet-gecontroleerde context in vergelijking met de gebruikersgedefinieerde operators in .NET 6 en eerdere versies. U kunt deze gedragswijziging tegenkomen bij het upgraden naar .NET 7.
Lijst met betrokken API's
| Operator | Context | In .NET 7 | In .NET 6 en eerder | Voorbeeld |
|---|---|---|---|---|
| operator +(IntPtr, int) | gecontroleerd | Werpt wanneer overlopen | Gooi niet wanneer overloopt | checked(intPtrVariable + 2); |
| operator -(IntPtr, int) | aangevinkt | Werpt wanneer overlopen | Gooit niet bij een overflow | checked(intPtrVariable - 2); |
| explicit operator IntPtr(long) | niet aangevinkt | Gooit niet bij overflow | Kan 32-bits contexten genereren | (IntPtr)longVariable; |
| expliciete operator void*(IntPtr) | aangevinkt | werpt wanneer overlopen | Gooit niet bij overflow | checked((void*)intPtrVariable); |
| expliciete operator IntPtr(void*) | gecontroleerd | werpt wanneer overlopen | Gooit niet bij overflow | checked((IntPtr)voidPtrVariable); |
| expliciete operator int (IntPtr) | niet aangevinkt | Gooit niet wanneer overlopen | Kan 64-bits contexten genereren | (int)intPtrVariable; |
| operator +(UIntPtr, int) | gecontroleerd | Werpt wanneer overlopen | Gooit niet wanneer overlopen | checked(uintPtrVariable + 2); |
| operator -(UIntPtr, int) | gecontroleerd | Werpt wanneer overlopen | Gooit niet wanneer overlopen | checked(uintPtrVariable - 2); |
| expliciete operator UIntPtr(ulong) | niet aangevinkt | Gooit niet wanneer overlopen | Kan 32-bits contexten genereren | (UIntPtr)uLongVariable |
| expliciete operator uint (UIntPtr) | niet aangevinkt | Gooit niet wanneer overlopen | Kan 64-bits contexten genereren | (uint)uintPtrVariable |
Hoe schendingen op te lossen
Controleer uw code om te bepalen of de gemarkeerde expressie een gedragswijziging kan veroorzaken en kies een geschikte manier om de diagnose op te lossen met de volgende opties:
Herstelopties
- Als de expressie geen gedragswijziging veroorzaakt:
- Als het
IntPtrofUIntPtrtype wordt gebruikt als systeemeigenintofuint, wijzigt u het type innintofnuint. - Als het
IntPtrofUIntPtrtype wordt gebruikt als systeemeigen aanwijzer, wijzigt u het type in het bijbehorende systeemeigen aanwijzertype. - Als u het type variabele niet kunt wijzigen, onderdrukt u de waarschuwing.
- Als het
- Als de expressie een gedragswijziging kan veroorzaken, verpakt u de expressie met een
checked- ofunchecked-instructie om het vorige gedrag te behouden.
Voorbeeld
Schending:
using System;
public unsafe class IntPtrTest
{
IntPtr intPtrVariable;
long longVariable;
void Test ()
{
checked
{
IntPtr result = intPtrVariable + 2; // Warns: Starting with .NET 7 the operator '+' will throw when overflowing in a checked context. Wrap the expression with an 'unchecked' statement to restore the .NET 6 behavior.
result = intPtrVariable - 2; // Starting with .NET 7 the operator '-' will throw when overflowing in a checked context. Wrap the expression with an 'unchecked' statement to restore the .NET 6 behavior.
void* voidPtrVariable = (void*)intPtrVariable; // Starting with .NET 7 the explicit conversion '(void*)IntPtr' will throw when overflowing in a checked context. Wrap the expression with an 'unchecked' statement to restore the .NET 6 behavior.
result = (IntPtr)voidPtrVariable; // Starting with .NET 7 the explicit conversion '(IntPtr)void*' will throw when overflowing in a checked context. Wrap the expression with an 'unchecked' statement to restore the .NET 6 behavior.
}
intPtrVariable = (IntPtr)longVariable; // Starting with .NET 7 the explicit conversion '(IntPtr)Int64' will not throw when overflowing in an unchecked context. Wrap the expression with a 'checked' statement to restore the .NET 6 behavior.
int a = (int)intPtrVariable; // Starting with .NET 7 the explicit conversion '(Int32)IntPtr' will not throw when overflowing in an unchecked context. Wrap the expression with a 'checked' statement to restore the .NET 6 behavior.
}
}
Herstel:
- Als de expressie geen gedragswijziging veroorzaakt en het
IntPtrofUIntPtrtype wordt gebruikt als systeemeigenintofuint, wijzigt u het type innintofnuint.
using System;
public unsafe class IntPtrTest
{
nint intPtrVariable; // type changed to nint
long longVariable;
void Test ()
{
checked
{
nint result = intPtrVariable + 2; // no warning
result = intPtrVariable - 2;
void* voidPtrVariable = (void*)intPtrVariable;
result = (nint)voidPtrVariable;
}
intPtrVariable = (nint)longVariable;
int a = (int)intPtrVariable;
}
}
- Als de expressie een gedragswijziging kan veroorzaken, wikkel deze in een
checked- ofunchecked-verklaring om het vorige gedrag te behouden.
using System;
public unsafe class IntPtrTest
{
IntPtr intPtrVariable;
long longVariable;
void Test ()
{
checked
{
IntPtr result = unchecked(intPtrVariable + 2); // wrap with unchecked
result = unchecked(intPtrVariable - 2);
void* voidPtrVariable = unchecked((void*)intPtrVariable);
result = unchecked((IntPtr)voidPtrVariable);
}
intPtrVariable = checked((IntPtr)longVariable); // wrap with checked
int a = checked((int)intPtrVariable);
}
}
Wanneer waarschuwingen onderdrukken
Als de expressie geen gedragswijziging veroorzaakt, is het veilig om een waarschuwing van deze regel te onderdrukken.