CA1833 : Utiliser AsSpan ou AsMemory à la place d’indexeurs basés sur Range pour obtenir la partie Span ou Memory d’un tableau

Propriété Value
Identificateur de la règle CA1833
Titre Utiliser AsSpan ou AsMemory à la place d’indexeurs basés sur Range pour obtenir la partie Span ou Memory d’un tableau
Catégorie Performances
Le correctif est cassant ou non cassant Sans rupture
Activé par défaut dans .NET 8 À titre de suggestion

Cause

Lors de l’utilisation d’un indexeur de plage sur un tableau et de l’affectation implicite de la valeur à Span<T> ou Memory<T>.

Description de la règle

L’indexeur de plage sur un Span<T> est une opération Slice sans copie. Toutefois, pour l’indexeur de plage sur un tableau, la méthode GetSubArray est utilisée à la place de Slice, ce qui produit une copie de la partie demandée du tableau. Cette copie est généralement inutile lorsqu’elle est implicitement utilisée comme valeur Span<T> ou Memory<T>. Si vous ne prévoyez pas d’effectuer une copie, utilisez la méthode AsSpan ou AsMemory pour éviter la copie inutile. Si la copie est prévue, affectez-la d’abord à une variable locale ou ajoutez un cast explicite. L’analyseur signale uniquement lorsqu’un cast implicite est utilisé sur le résultat de l’opération d’indexeur de plage.

Détecte

Conversions implicites :

  • Span<SomeT> slice = arr[a..b];
  • Memory<SomeT> slice = arr[a..b];

Ne détecte pas

Conversions explicites :

  • Span<SomeT> slice = (Span<SomeT>)arr[a..b];
  • Memory<SomeT> slice = (Memory<SomeT>)arr[a..b];

Comment corriger les violations

Pour corriger la violation de cette règle, utilisez la méthode d’extension AsSpan ou AsMemory afin d’éviter de créer des copies de données inutiles.

class C
{
    public void TestMethod(byte[] arr)
    {
        // The violation occurs for both statements below
        Span<byte> tmp2 = arr[0..5];
        Memory<byte> tmp4 = arr[5..10];
        ...
    }
}
class C
{
    public void TestMethod(byte[] arr)
    {
        // The violations fixed with AsSpan or AsMemory accordingly
        Span<byte> tmp2 = arr.AsSpan()[0..5];
        Memory<byte> tmp4 = arr.AsMemory()[5..10];
        ...
    }
}

Conseil

Un correctif de code est disponible pour cette règle dans Visual Studio. Pour l’utiliser, positionnez le curseur sur la violation et appuyez sur Ctrl+. (point). Choisissez Utiliser AsMemory au lieu de l’indexeur basé sur une plage sur un tableau dans la liste des options présentées.

Code fix for CA1833 - Use AsSpan or AsMemory instead of Range-based indexers for getting Span or Memory portion of an array

Vous pouvez également éviter cet avertissement en ajoutant un cast explicite.

class C
{
    public void TestMethod(byte[] arr)
    {
        // The violation occurs
        Span<byte> tmp1 = arr[0..5];
        Memory<byte> tmp2 = arr[5..10];
        ...
    }
}
class C
{
    public void TestMethod(byte[] arr)
    {
        // The violation fixed with explicit casting
        Span<byte> tmp1 = (Span<byte>)arr[0..5];
        Memory<byte> tmp2 = (Memory<byte>)arr[5..10];
        ...
    }
}

Quand supprimer les avertissements

Vous pouvez supprimer sans risque une violation de cette règle si la création d’une copie est prévue.

Supprimer un avertissement

Si vous voulez supprimer une seule violation, ajoutez des directives de préprocesseur à votre fichier source pour désactiver et réactiver la règle.

#pragma warning disable CA1833
// The code that's violating the rule is on this line.
#pragma warning restore CA1833

Pour désactiver la règle sur un fichier, un dossier ou un projet, définissez sa gravité sur none dans le fichier de configuration.

[*.{cs,vb}]
dotnet_diagnostic.CA1833.severity = none

Pour plus d’informations, consultez Comment supprimer les avertissements de l’analyse de code.

Voir aussi