Question

Je pensais que cette méthode était valide, mais je me suis trompé:

static void Equals<T>(T x, T y)
{
    return x == y;    //operator == can't be applied to type T
}

Après avoir lu le specifiation (§7.2.4 en v3.0 et §7.3.4 en v4.0):

7.2.4 résolution de surcharge de l'opérateur binaire

Une opération de la forme x op y, op est un surchargeable opérateur binaire, x est une expression de de type X et Y est une expression de type Y, est traitée comme suit:

  • L'ensemble des opérateurs définis par l'utilisateur candidats fourni par X et Y pour le fonctionnement op opérateur (x, y) est déterminée. le ensemble se compose de l'union de la opérateurs candidats fournis par X et les opérateurs candidats fournis par Y, chaque déterminée en utilisant les règles de §7.2.5. Si X et Y sont du même type, ou si X et Y sont dérivés d'un type de base commune, puis partagée les opérateurs candidats ne se produisent que dans la ensemble combiné une fois.

  • Si l'ensemble des candidats opérateurs définis par l'utilisateur est pas vide, cela devient l'ensemble des opérateurs candidats à la opération. Dans le cas contraire, le calendrier prédéfini implémentations binaires opérateur op, y compris leurs formes levées, devenir l'ensemble des opérateurs candidats à la opération. la prédéfini les mises en œuvre d'un opérateur donné sont précisés dans la description l'opérateur (§7.7 par §7.11).

  • Les règles de résolution de surcharge de §7.4.3 sont appliqués à l'ensemble des opérateurs candidats pour choisir le meilleur opérateur en ce qui concerne la liste des arguments (x, y), et cet opérateur devient le résultat de la résolution de surcharge processus. Si la résolution de surcharge ne choisit pas un seul meilleur opérateur, une erreur de compilation se produit.

A l'étape 2, je pense qu'il faut appliquer cette mise en œuvre prédéfinie:

bool operator ==(object x, object y);
bool operator !=(object x, object y);

puisque tout en C # provient de l'objet. Comment une erreur de compilation se produit à l'étape 3? Je ne pense pas qu'il soit possible que « la résolution de surcharge ne choisit pas » dans ce cas.

EDIT La question est venue à l'esprit quand j'exécutait quelque chose comme ceci:

class EnumComparer<TEnum> : IEqualityComparer<TEnum>
{
    public bool Equals(TEnum x, TEnum y)
    {
        return x == y;
    }
    public int GetHashCode(TEnum obj)
    {
        return (int)obj;
    }
}

Je crains besoin de construire une expression et l'invoquons dynamicly dans la méthode de Equals.

Était-ce utile?

La solution

Bon pour vous pour la lecture de la spécification, mais vous avez cessé de lire trop tôt. Si vous aviez lu plus loin, vous auriez obtenu ce bit:


Les opérateurs d'égalité de type référence prédéfinis nécessitent une des opérations suivantes:

  • Les deux opérandes sont une valeur d'un type connu pour être un type de référence ou la valeur nulle littérale. En outre, une conversion de référence explicite existe à partir du type de l'un des opérandes du type de l'autre opérande.

  • Un opérande est une valeur de type T, où T est un paramètre de type et l'autre opérande est la valeur nulle littérale. En outre T n'a pas la contrainte de type valeur.

À moins une de ces conditions sont vraies, une erreur de temps de liaison se produit. (*)


L'erreur est pas de résolution de surcharge; l'erreur est que la résolution de surcharge aurait choisi l'opérateur d'égalité de type référence prédéfinie, et vous n'avez pas les types de référence.

Considérez votre code. Ce qui empêche T d'être un type de valeur sans opérateur d'égalité défini sur elle? Rien. Supposons que nous est retombé à la version de l'objet; Les deux opérandes seraient COLIS à des endroits différents et donc-inégale référence, même si elles avaient le même contenu. Depuis est lent, la confusion et le mal, il est illégal de même essayer.

Pourquoi essayez-vous de faire cette chose en premier lieu? Si votre méthode a fonctionné, qu'il n'a pas, votre méthode serait pire que d'utiliser simplement == en premier lieu. Quelle est la valeur que vous avez l'intention d'ajouter au monde avec cette méthode?


(*) Je l'ai signalé l'erreur grammaticale dans cette phrase aux mainteneurs spécifications.

Autres conseils

Ce serait peut fonctionner si elle savait que where T : class, en faisant une comparaison de référence. Les opérateurs ont généralement très peu de soutien avec les génériques, mais il y a des solutions de contournement. MiscUtil offre pour les opérateurs sur les génériques, sinon EqualityComparer<T>.Default.Equals(x,y) est bon choix.

Je aime utiliser EqualityComparer<T>.Default pour cela.

Il est basé sur la méthode Equals surchargée, mais utilise IEquatable<T> lorsqu'il est disponible, en évitant la boxe sur les types de valeur pour son application.

EqualityComparer<T>.Default.Equals(x, y)

méthode de l'utilisation .Equals() et assurez-vous que la mise en œuvre T IComparable

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top