Delen via


CA2020: Gedragswijziging voorkomen die wordt veroorzaakt door ingebouwde operators van IntPtr/UIntPtr

Eigenschappen Weergegeven als
Regel-id CA2020
Titel Gedragswijziging voorkomen die wordt veroorzaakt door ingebouwde operators van IntPtr/UIntPtr
Categorie Betrouwbaarheid
Oplossing is brekend of niet-brekend Niet-brekend
Standaard ingeschakeld in .NET 9 Als suggestie

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 overlopen binnen de gecontroleerde context of niet in niet-gecontroleerde context genereren in vergelijking met de vorige door de gebruiker gedefinieerde 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 Opmerking
operator +(IntPtr, int) geselecteerd Werpt wanneer overlopen Gooit niet wanneer overlopen checked(intPtrVariable + 2);
operator -(IntPtr, int) geselecteerd Werpt wanneer overlopen Gooit niet wanneer overlopen checked(intPtrVariable - 2);
expliciete operator IntPtr(long) niet ingeschakeld Gooit niet wanneer overlopen Kan 32-bits contexten genereren (IntPtr)longVariable;
expliciete operator void*(IntPtr) geselecteerd werpt wanneer overlopen Gooit niet wanneer overlopen checked((void*)intPtrVariable);
expliciete operator IntPtr(void*) geselecteerd werpt wanneer overlopen Gooit niet wanneer overlopen checked((IntPtr)voidPtrVariable);
expliciete operator int (IntPtr) niet ingeschakeld Gooit niet wanneer overlopen Kan 64-bits contexten genereren (int)intPtrVariable;
operator +(UIntPtr, int) geselecteerd Werpt wanneer overlopen Gooit niet wanneer overlopen checked(uintPtrVariable + 2);
operator -(UIntPtr, int) geselecteerd Werpt wanneer overlopen Gooit niet wanneer overlopen checked(uintPtrVariable - 2);
expliciete operator UIntPtr(ulong) niet ingeschakeld Gooit niet wanneer overlopen Kan 32-bits contexten genereren (UIntPtr)uLongVariable
expliciete operator uint (UIntPtr) niet ingeschakeld Gooit niet wanneer overlopen Kan 64-bits contexten genereren (uint)uintPtrVariable

Schendingen oplossen

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:

Oplossingsopties:

  • Als de expressie geen gedragswijziging veroorzaakt:
    • Als het IntPtr of UIntPtr type wordt gebruikt als systeemeigen int of uint, wijzigt u het type in nint of nuint.
    • Als het IntPtr of UIntPtr type 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 de expressie een gedragswijziging kan veroorzaken, verpakt u deze met een checked of unchecked een instructie om het vorige gedrag te behouden.

Opmerking

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

Oplossing:

  • Als de expressie geen gedragswijziging veroorzaakt en het IntPtr of UIntPtr type wordt gebruikt als systeemeigen int of uint, wijzigt u het type in nint of nuint.
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, verpakt u deze met een checked of unchecked een instructie 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.

Zie ook