【问题标题】:LinkedList.Contains. What is the method used to compare objects?链表。包含。用于比较对象的方法是什么?
【发布时间】:2009-11-18 11:22:25
【问题描述】:

LinkedList.Contains 方法。 (.NET 2)

里面的对象是如何比较的? (等于?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)));
}

【问题讨论】:

  • (以完整示例回复评论)

标签: .net linked-list contains


【解决方案1】:

由于链表不是字典,我希望它使用EqualityComparer&lt;T&gt;.Default.Equals(x,y)

这支持(按顺序):

  • IEquatable&lt;T&gt;(针对有问题的T
  • object.Equals(默认使用引用相等,或支持覆盖的Equals(object)

请注意,EqualityComparer&lt;T&gt; 还为两个类和Nullable&lt;T&gt; 处理通常的null 规则等。

(更新:检查并正确;来自Find(T)

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

根据 cmets,更新以证明 ISomeInterface: IEquatable&lt;ISomeInterface&gt; 有效:

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(); }
}

【讨论】:

  • 是的,你能看到我在主题中发布的代码吗?问题是linkedList 包含一个接口。但对象也实现了 IEquitable 接口。
  • 不同的T;他们需要为LinkedList&lt;IClass&gt; 实现IEquatable&lt;IClass&gt; 才能使用它。
  • 或者更具体地说,您需要IClass : IEquatable&lt;IClass&gt;,因为它对于所有 IClass 实现都必须是正确的。
  • 不,如果 linkedList T 类型不是实现 IEquitable 的类型,则实现 IEquitable 是不够的。在这种情况下,我需要重写对象 Equals 方法。
  • 是的 - 请参阅更新中的示例(以及我在上面的评论)
【解决方案2】:

实现的方法是Equals。我需要实现基本的 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);
        }
    }
}

【讨论】:

  • @serhio:仅供参考,一般来说,像这样的东西会被编辑到你的问题中[尽管你可能一开始就没有点数]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多