2009-11-18 6 views
3

Méthode LinkedList.Contains. (.NET 2)LinkedList.Contains. Quelle est la méthode utilisée pour comparer les objets?

Comment les objets sont comparés à l'intérieur? (Equals? CompareTo?)

MSDN ne dit rien à propos de.

la situation:

interface IClass 
{ 
    string GetName(); 
} 

class Class1 : IClass, IEquatable<Class1> 
{ 
    public string FirstName; 
    public string LastName; 

    string IClass.GetName() { return FirstName; } 

    bool IEquatable<Class1>.Equals(Class1 other) 
    { 
     return FirstName.Equals(other.FirstName); 
    } 
} 

class Class2 : IClass, IEquatable<Class2> 
{ 
    public string FirstName; 
    public string LastName; 

    string IClass.GetName() { return LastName; } 

    bool IEquatable<Class2>.Equals(Class2 other) 
    { 
     return LastName.Equals(other.LastName); 
    } 
} 

public void TestMethod() 
{ 
    Class1 c1 = new Class1(); 
    c1.FirstName = "fn"; 
    c1.FirstName = "ln"; 

    Class2 c2 = new Class2(); 
    c2.FirstName = "fn"; 
    c2.FirstName = "ln"; 

    Class1 c3 = new Class1(); 
    c3.FirstName = "fn"; 
    c3.FirstName = "ln"; 

    LinkedList<IClass> myList = new LinkedList<IClass>(); 
    myList.AddFirst(c1); 
    myList.AddFirst(c2); 
    // false here 
    MessageBox.Show("myList<IClass> contains c3? - " + (myList.Contains(c3))); 

    LinkedList<Class1> myList1 = new LinkedList<Class1>(); 
    myList1.AddFirst(c1); 
    myList1.AddFirst(c1); 
    // true here 
    MessageBox.Show("myList1<Class1> contains c3? - " + (myList1.Contains(c3))); 
} 
+0

(a répondu à commenter l'exemple complet) –

+0

[réflecteur] (http://reflector.red-gate.com) –

Répondre

1

La méthode à mettre en œuvre est le Équivaut à. J'ai besoin d'implémenter la méthode de base Equals, et pas nécessairement (?!) la générique.

class Class1 : IClass, IEquatable<Class1> 
{ 
    public string FirstName; 
    public string LastName; 

    string IClass.GetName() { return FirstName; } 

    bool IEquatable<Class1>.Equals(Class1 other) 
    { 
     return FirstName.Equals(other.FirstName); 
    } 

    public override bool Equals(object obj) 
    { 
     if (obj is Class1) 
     { 
      return this.FirstName.Equals((obj as Class1).FirstName); 
     } 
     else 
     { 
      return base.Equals(obj); 
     } 
    } 
} 
+0

@serhio: FYI en général des trucs comme ceci est édité dans votre question [même si vous n'avez pas eu alors des points au début] –

+0

c'est déjà une réponse J'ai trouvé, pas une partie de la question. – serhio

6

Comme une liste chaînée est pas un dictionnaire, je attendre à utiliser EqualityComparer<T>.Default.Equals(x,y).

Ce soutien (dans l'ordre):

  • IEquatable<T> (pour la T en question)
  • object.Equals (qui utilise l'égalité de référence par défaut, ou prend en charge une substitution Equals(object))

Remarque que EqualityComparer<T> gère également les règles habituelles null etc pour les deux classes et Nullable<T>.

(mise à jour: vérifié et correcte, à partir Find(T))

... 
EqualityComparer<T> comparer = EqualityComparer<T>.Default; 
... 
if (comparer.Equals(head.item, value)) {...} 
... 

mise à jour pour prouver ce travail quand ISomeInterface: IEquatable<ISomeInterface>, selon les commentaires:

using System; 
using System.Collections.Generic; 


class Program 
{ 
    static void Main() 
    { 
     LinkedList<IFoo> foos = new LinkedList<IFoo>(); 
     foos.AddLast(new Foo1("abc")); 
     foos.AddLast(new Foo2("def")); 
     Console.WriteLine("checking contains..."); 
     bool c = foos.Contains(new Foo1("ghi")); 
     Console.WriteLine("...done"); 
    } 
} 
interface IFoo : IEquatable<IFoo> 
{ 
    void Bar(); 
} 
class Foo1 : IFoo 
{ 
    public string Value { get; set; } 
    public Foo1(string value) { Value = value; } 
    public override bool Equals(object other) 
    { 
     Console.WriteLine(Value + " > override Equals"); 
     return base.Equals(other); 
    } 
    bool IEquatable<IFoo>.Equals(IFoo other) 
    { 
     Console.WriteLine(Value + " > explicit Equals"); 
     return base.Equals(other); 
    } 
    public void Bar() { } 
    public override int GetHashCode() { return base.GetHashCode(); } 
} 
class Foo2 : IFoo 
{ 
    public string Value { get; set; } 
    public Foo2(string value) { Value = value; } 
    public override bool Equals(object other) 
    { 
     Console.WriteLine(Value + " > override Equals"); 
     return base.Equals(other); 
    } 
    public bool Equals(IFoo other) 
    { 
     Console.WriteLine(Value + " > implicit Equals"); 
     return base.Equals(other); 
    } 
    public void Bar() { } 
    public override int GetHashCode() { return base.GetHashCode(); } 
} 
+0

oui, pourriez-vous voir le code I a écrit dans le sujet? le problème est que la listeLiée contient une interface. Mais les objets implémente également l'interface IEquitable. – serhio

+0

Différent 'T'; ils devraient implémenter 'IEquatable ' pour 'LinkedList ' pour l'utiliser. –

+0

Ou plus spécifiquement, vous auriez besoin de 'IClass: IEquatable ', comme cela doit être vrai pour les implémentations ** all ** 'IClass'. –

Questions connexes