2009-11-18 4 views
3

Метод LinkedList.Contains. (.NET 2)LinkedList.Contains. Каков метод, используемый для сравнения объектов?

Как объекты сравниваются внутри? (Equals? CompareTo?)

MSDN ничего не говорит.

ситуация:

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

(ответил на комментарий с полным примером) –

+0

[Отражатель] (http://reflector.red-gate.com) –

ответ

1

Метод реализации является Равно. Мне нужно реализовать базовый метод Equals, а не обязательно (?!) общий.

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 в общем случае вроде этого будет отредактирован в ваш вопрос [хотя вы, возможно, не имели тогда точек в начале] –

+0

, это уже ответ, который Я нашел, а не вопрос. – serhio

6

Поскольку связанный список не является словарем, я бы ожидать его использовать EqualityComparer<T>.Default.Equals(x,y).

Это поддерживает (в произвольном порядке):

  • IEquatable<T> (для T в вопросе)
  • object.Equals (который использует равенство ссылок по умолчанию, или поддерживает переопределены Equals(object))

Примечание что EqualityComparer<T> также обрабатывает обычные правила null и т. д. для обоих классов и Nullable<T>.

(обновление: проверено, и правильно, от Find(T))

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

Update, чтобы доказать эту работу, когда ISomeInterface: IEquatable<ISomeInterface>, согласно комментариям:

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

да, могли бы вы увидеть код, который я отвечал в этой теме? проблема заключается в том, что связанныйList содержит интерфейс. Но объекты также реализуют интерфейс IEquitable. – serhio

+0

Различные 'T'; им понадобится реализовать 'IEquatable ' для 'LinkedList ', чтобы использовать его. –

+0

Или, более конкретно, вам понадобится 'IClass: IEquatable ', так как это должно быть истинно для ** всех ** 'IClass'-реализаций. –