2010-11-16 10 views
1

J'ai deux listes génériques avec les mêmes objets Type T en leur sein. Par exemple oGenList1.Items(0) est le même que oGenList2.Items(3) (leurs propriétés ont les mêmes valeurs, etc).
que je fais quelque chose comme ceci:Generic.List - comment fonctionne la fonction Contient?

oGenList2.Contains(oGenList1.Items(0)) 

Il montre toujours false; Je ne comprends pas pourquoi. Avez-vous une idée? Dois-je définir un comparateur pour la classe T pour forcer cette fonction à fonctionner correctement?

J'ai déjà ajouté la fonction Equals et cela ne fonctionne toujours pas. :(Je ai fait une simple simulation de ma situation dans le projet très simple et cela fonctionne Mais ma situation est plus complexe.. Mes classes héritent d'autres, etc. ceux Toute idée pourquoi il ne fonctionne pas?

Répondre

5

Par défaut, vous utilisez la méthode Equals de votre type Vous n'avez pas besoin de définir un comparateur personnalisé, si votre scénario est aussi simple (vous voulez juste Contains se comporter correctement), remplacez simplement la méthode Equals de votre type pour comparer deux objets pour l'égalité basé sur les critères que vous voulez et vous devriez être bon. (Oh, et si vous surchargez Equals, vous devez également remplacer GetHashCode)

exemple de base:

class X : IEquatable<X> 
{ 
    public int Value { get; set; } 

    public bool Equals(X other) 
    { 
     return other != null && other.Value == Value; 
    } 

    // This is the main part you need to do. Otherwise by default 
    // object.Equals just tests for reference equality. 
    public override bool Equals(object obj) 
    { 
     return Equals(obj as X); 
    } 

    public override int GetHashCode() 
    { 
     return Value; 
    } 
} 

public class Program 
{ 
    public static void Main() 
    { 
     var list1 = new List<X> { new X { Value = 1 } }; 
     var list2 = new List<X> { new X { Value = 1 } }; 

     // Since type X overrides the Equals method to test 
     // the equality of two instances' properties, this line 
     // outputs True. 
     Console.WriteLine(list2.Contains(list1[0])); 
    } 
} 
2

IIRC, cela utilisera EqualityComparer<T>.Default pour faire la comparaison. Ce premier test pour voir si votre type T implémente IEquatable<T> - si c'est le cas, il utilisera cette interface et la méthode Equals(T). Sinon, il utilisera simplement object.Equals(object) (notez qu'il prend également en compte null s et Nullable<T>, donc vous n'avez pas à le faire).

Par défaut, cela signifie que les classes ne seront traitées comme égales que si elles sont identiques (les structures sont comparées au niveau du champ). Si vous remplacez Equals, vous devriez obtenir le comportement que vous attendez, mais notez que si vous surchargez Equals, vous devez également remplacer GetHashCode pour avoir une implémentation similaire.