Share via


CA2020: Az IntPtr/UIntPtr beépített operátorai által okozott viselkedésváltozás megakadályozása

Tulajdonság Érték
Szabályazonosító CA2020
Cím Az IntPtr/UIntPtr beépített operátorai által okozott viselkedésváltozás megakadályozása
Kategória Megbízhatóság
A javítás kompatibilitástörő vagy nem törik Nem törés
Alapértelmezés szerint engedélyezve a .NET 8-ban Javaslatként

Ok

Ez a szabály akkor aktiválódik, ha viselkedésbeli változást észlel a .NET 6 és a .NET 7 között, amelyet az és UIntPtraz új beépített operátorok IntPtr vezetnek be.

Szabály leírása

A numerikus IntPtr funkcióvalIntPtrUIntPtr beépített operátorokat szerzett a konverziókhoz, a nem naplós műveletekhez és a bináris műveletekhez. Ezek az operátorok akkor jelenhetnek meg, ha túlcsordulnak az ellenőrzött környezetben, vagy nem jelennek meg a nem ellenőrzött környezetek a .NET 6 és a korábbi verziók korábbi, felhasználó által definiált operátoraihoz képest. Ez a viselkedésbeli változás a .NET 7-re való frissítéskor előfordulhat.

Érintett API-k listája

Operator Környezet A .NET 7-ben A .NET 6-os és korábbi verzióiban Példa
operátor +(IntPtr, int) bejelölve Túlcsorduláskor dob Nem dob túlcsorduláskor checked(intPtrVariable + 2);
operátor –(IntPtr, int) bejelölve Túlcsorduláskor dob Nem dob túlcsorduláskor checked(intPtrVariable - 2);
explicit operátor IntPtr(long) Ellenőrizetlen Nem dob túlcsorduláskor 32 bites környezetek bedobása (IntPtr)longVariable;
explicit operátor void*(IntPtr) bejelölve túlcsorduláskor Nem dob túlcsorduláskor checked((void*)intPtrVariable);
explicit operátor IntPtr(void*) bejelölve túlcsorduláskor Nem dob túlcsorduláskor checked((IntPtr)voidPtrVariable);
explicit operátor int(IntPtr) Ellenőrizetlen Nem dob túlcsorduláskor 64 bites környezetekbe is bedobható (int)intPtrVariable;
operátor +(UIntPtr, int) bejelölve Túlcsorduláskor dob Nem dob túlcsorduláskor checked(uintPtrVariable + 2);
operátor –(UIntPtr, int) bejelölve Túlcsorduláskor dob Nem dob túlcsorduláskor checked(uintPtrVariable - 2);
explicit operátor UIntPtr(ulong) Ellenőrizetlen Nem dob túlcsorduláskor 32 bites környezetek bedobása (UIntPtr)uLongVariable
explicit operátor uint(UIntPtr) Ellenőrizetlen Nem dob túlcsorduláskor 64 bites környezetekbe is bedobható (uint)uintPtrVariable

Szabálysértések kijavítása

Vizsgálja meg a kódot, és állapítsa meg, hogy a megjelölt kifejezés viselkedésbeli változást okozhat-e, és válasszon egy megfelelő módszert a diagnosztikának a következő lehetőségek közül:

Javítás beállításai:

  • Ha a kifejezés nem okoz viselkedésbeli változást:
    • Ha a IntPtr típus UIntPtr natívként int van használva, vagy uintmódosítsa a típust a következőre nint : vagy nuint.
    • Ha a IntPtr rendszer UIntPtr natív mutatóként használja a típust, módosítsa a típust a megfelelő natív mutatótípusra.
    • Ha nem tudja módosítani a változó típusát, tiltsa le a figyelmeztetést.
  • Ha a kifejezés viselkedésbeli változást okozhat, csomagolja be egy vagy unchecked több checked utasítással az előző viselkedés megőrzése érdekében.

Példa

Szabálysértés:

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

Javítás:

  • Ha a kifejezés nem okoz viselkedésbeli változást, és a rendszer natívként használja a IntPtr kifejezést vagy UIntPtr a típust, módosítsa a típust vagy nuinta típustnint.intuint
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;
    }
}
  • Ha a kifejezés viselkedésbeli változást okozhat, csomagolja be egy vagy unchecked több checked utasítással az előző viselkedés megőrzése érdekében.
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);
    }
}

Mikor kell letiltani a figyelmeztetéseket?

Ha a kifejezés nem okoz viselkedésbeli változást, nyugodtan letilthatja a szabály figyelmeztetését.

Kapcsolódó információk