10
votes

Comment la liste .indexof () effectue-t-elle des comparaisons sur des objets personnalisés?

J'ai écrit une classe d'objets de compte et contient une liste statique de ces objets de compte. Mon programme a bouclé chaque compte dans la liste, effectuant des travaux avec le compte, puis réinitialisant en haut lorsqu'il atteint la fin de la liste.

Mon problème est que je dois être en mesure de réinsérer le compte dans la liste après la fin de mon programme de travailler avec elle, avec des informations mises à jour ajoutées. Puis-je faire cela comme écrit ci-dessous, à l'aide de la fonction Indexof () pour vérifier l'objet dans la liste statique ou échouera-t-il parce que je l'ai ajouté de données? Je ne comprends pas quels domaines il compare pour voir si les deux objets sont les mêmes.

Remarque: aucun doublure n'est autorisé dans la liste, il n'ya donc aucun risque de mettre à jour le mauvais article xxx


3 commentaires

J'ai édité votre titre. S'il vous plaît voir, " Les questions incluent" Tags "dans leurs titres? ", où le consensus est "non, ils devraient ne pas".


Avez-vous vérifié le Documentation ? Il est indiqué "Cette méthode détermine l'égalité à l'aide du comparateur d'égalité par défaut Equalitomerer .default pour T, type de valeurs de la liste."


Si vous ne vous souciez pas de la commande une fois que vous avez implémenté soit un personnalisé ou avez un support de compte iéquatie Vous pouvez être mieux éteint à l'aide d'un hashset SEANCE Vous n'avez pas de doublons.


5 Réponses :


10
votes

Votre objet doit implémenter le Iequatable interface et remplacer le Égale code> méthode.

public class Account : IEquatable<Account>
{
    public string name;
    public string password;
    public string newInfo;

    public bool Equals(Account other)
    {
       //Choose what you want to consider as "equal" between Account objects  
       //for example, assuming newInfo is what you want to consider a match
       //(regardless of case)
       if (other == null) 
             return false;

       return String.Equals(this.newInfo, other.newInfo, 
                           StringComparison.OrdinalIgnoreCase);
    }
}


6 commentaires

En réalité, l'interface appropriée est Iequatable comme définie la méthode Equals et est utilisée par indexof dans les collections génériques. IéqualityComparer est utilisé par un objet distinct qui n'a que le seul but est de comparer deux objets de type t .


J'apprécie vraiment l'exemple. Je suis toujours nouveau et j'apprendrais cela comme un passe-temps, donc une explication technique est beaucoup plus difficile à visualiser que le code.


Vous devez également remplacer gethascode () voir la section Notes sur les implémentations section de la page pour IEQUABLE : " Si vous Implémenter Iequatable , vous devez également remplacer les implémentations de la classe de base de objet.equals (objet) et gethascode afin que leur comportement soit cohérent avec celle de la méthode anéqualable . "


@Blizz - Scott a ajouté des informations supplémentaires dans sa réponse importante (non requise pour l'index de l'index de l'index mais devrait être mise en œuvre indépendamment). Vous pouvez surmonter le mien comme réponse et accepter son.


Vous n'avez même pas besoin de le faire implémenter Iequatable . Il suffit de remplacer égaux (objet) et gethashcode le fera. De plus, il y a des dangers pour mettre en œuvre iéquatif sur une classe non scellée. Voir blog.mischel.com/2013/ 01/05 / ...


@Jimmischel - Je n'avais pas rencontré cela auparavant, merci pour le lien!



4
votes

Si votre classe implémente correctement IEQUABLE , puis indexofof () utilisera votre Equals () méthode pour tester l'égalité.

sinon, indexofof () utilisera l'égalité de référence.


0 commentaires

10
votes

Une chose la réponse acceptée n'a pas couvert est que vous êtes censé remplacer égaux (objet) et gethascode () pour iéquatif travailler correctement. Voici la mise en œuvre complète (basée sur Réponse du clavier ) xxx


3 commentaires

+1 - Cela devrait être la réponse acceptée. L'appel n'utilise pas cela afaik, c'est pourquoi mon code a fonctionné, mais pour une utilisation générale, il n'y a aucune raison de ne pas le faire.


Merci j'ai mis à jour la réponse acceptée au cas où quelqu'un d'autre vient à travers elle


Il semble suffisant de remplacer simplement gethashcode et est égal à comme indiqué ci-dessus, sans implémenter iéquatif du tout.



13
votes

Une autre option consiste à utiliser list.findindex , et passez un prédicat. C'est-à-dire: xxx

de cette façon, vous pouvez rechercher sur n'importe quel champ arbitraire ou nombre de champs. Ceci est particulièrement utile si vous n'avez pas accès au code source du compte pour ajouter un surchargé d'égal méthode.


0 commentaires

0
votes

Vous pouvez utiliser un prédicat personnalisé pour votre classe, telle que: xxx

alors vous pouvez l'utiliser comme suit: xxx

Vous pouvez même modifier la classe IndeofName pour utiliser un drapeau pour basculer entre le type d'informations que vous recherchez. Ex: nom ou newinfo.


0 commentaires