通用函数中的equals()和==

pm1*_*100 5 c# equals

我正在对各种类型的集合操作进行比较.

所以我有一个泛型类

 public class Comparer<T, Tid>
...
     public bool Equals(T x, T y)
       {
          var xid = m_idfunc(x);
           var yid = m_idfunc(y);
           return (Tid)xid == (Tid)yid;
       }
Run Code Online (Sandbox Code Playgroud)

其中m_idfunc是传递给Comparer构造函数的lambda,它是

Func<T,Tid>
Run Code Online (Sandbox Code Playgroud)

我用Tid = string创建了一个比较器.我进入等于函数xid = string1,yid = string2

如果string1和string 2相同("foo"和"foo"说)

xid == yid
Run Code Online (Sandbox Code Playgroud)

产生错误

(Tid)xid == (Tid)yid
Run Code Online (Sandbox Code Playgroud)

也产生错误(它不应该是必要的 - 我只是变得绝望)

继承我的直接窗口 - 暂停返回xid == yid行

yid.GetType() == typeof(string)
true
xid.GetType() == typeof(string)
true
xid==yid
false
(string)xid==(string)yid
true
xid.Equals(yid)
true
Run Code Online (Sandbox Code Playgroud)

这是怎么回事?

Den*_*nis 0

我认为,使用EqualityComparer<TId>inside更正确Comparer<T, Tid>。此外,我将使用接口来获取标识符,而不是委托:

interface IObjectWithId<T>
{
    T Id { get; }
}

class IdEqualityComparer<T, TId> : EqualityComparer<T>
    where T : IObjectWithId<TId>
{
    public override bool Equals(T x, T y)
    {
        return EqualityComparer<TId>.Default.Equals(x.Id, y.Id);
    }

    public override int GetHashCode(T obj)
    {
        return EqualityComparer<TId>.Default.GetHashCode(obj.Id);
    }
}

class A : IObjectWithId<string>
{
    public string Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

用法:

var a = new A { Id = "foo" };
var b = new A { Id = "foo" };
var c = new A { Id = "bar" };

var comparer = new IdEqualityComparer<A, string>();

Console.WriteLine(comparer.Equals(a, b)); // true
Console.WriteLine(comparer.Equals(a, c)); // false
Run Code Online (Sandbox Code Playgroud)