CA1815 : Remplacez Equals et l'opérateur égal à dans les types valeur

Propriété Value
Identificateur de la règle CA1815
Titre Remplacez Equals et l'opérateur égal à dans les types valeur
Catégorie Performances
Le correctif est cassant ou non cassant Sans rupture
Activé par défaut dans .NET 8 Non

Cause

Un type valeur ne substitue pas System.Object.Equals ou n’implémente pas l’opérateur d’égalité (==). Cette règle ne vérifie pas les énumérations.

Par défaut, cette règle examine uniquement les types visibles en externe, mais elle est configurable.

Description de la règle

Pour les types valeur non-blittables, l’implémentation héritée de Equals utilise la bibliothèque System.Reflection pour comparer le contenu de tous les champs. Le processus de réflexion sollicite fortement les ressources informatiques et la comparaison de chaque champ à la recherche d'une égalité peut s'avérer inutile. Si des utilisateurs sont susceptibles de comparer ou de trier des instances, ou de les utiliser en tant que clés de table de hachage, votre type valeur doit implémenter Equals. Si votre langage de programmation prend en charge la surcharge des opérateurs, vous devez également fournir une implémentation des opérateurs d’égalité et d’inégalité.

Comment corriger les violations

Pour corriger une violation de cette règle, fournissez une implémentation de Equals. Si vous le pouvez, implémentez l’opérateur d’égalité.

Quand supprimer les avertissements

Vous pouvez sans risque supprimer un avertissement de cette règle si des instances du type valeur ne seront pas comparées les unes aux autres.

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 CA1815
// The code that's violating the rule is on this line.
#pragma warning restore CA1815

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.CA1815.severity = none

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

Configurer le code à analyser

Utilisez l’option suivante pour configurer les parties de votre codebase sur lesquelles exécuter cette règle.

Vous pouvez configurer cette option pour cette règle uniquement, pour toutes les règles auxquelles elle s’applique ou pour toutes les règles de cette catégorie (Performances) auxquelles elle s’applique. Pour plus d’informations, consultez Options de configuration des règles de qualité du code.

Inclure des surfaces d’API spécifiques

Vous pouvez configurer les parties de votre codebase sur lesquelles exécuter cette règle, en fonction de leur accessibilité. Par exemple, pour spécifier que la règle doit s’exécuter uniquement sur la surface d’API non publique, ajoutez la paire clé-valeur suivante à un fichier .editorconfig dans votre projet :

dotnet_code_quality.CAXXXX.api_surface = private, internal

Exemple

Le code suivant montre une structure (type valeur) qui enfreint cette règle :

// Violates this rule
public struct Point
{
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    public int X { get; }

    public int Y { get; }
}

Le code suivant corrige la violation précédente en substituant System.ValueType.Equals et en implémentant les opérateurs d’égalité (== et !=) :

public struct Point : IEquatable<Point>
{
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    public int X { get; }

    public int Y { get; }

    public override int GetHashCode()
    {
        return X ^ Y;
    }

    public override bool Equals(object? obj)
    {
        if (!(obj is Point))
            return false;

        return Equals((Point)obj);
    }

    public bool Equals(Point other)
    {
        if (X != other.X)
            return false;

        return Y == other.Y;
    }

    public static bool operator ==(Point point1, Point point2)
    {
        return point1.Equals(point2);
    }

    public static bool operator !=(Point point1, Point point2)
    {
        return !point1.Equals(point2);
    }
}

Voir aussi