EqualityComparer< T> .DEFAULT与T.Equals [英] EqualityComparer<T>.Default vs. T.Equals

查看:113
本文介绍了EqualityComparer< T> .DEFAULT与T.Equals的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个通用的 MyClass的< T> 需要比较这两类对象< T> 。通常我会做这样的事情......

Suppose I've got a generic MyClass<T> that needs to compare two objects of type <T>. Usually I'd do something like ...

void DoSomething(T o1, T o2)
{
  if(o1.Equals(o2))
  {
    ...
  }
}

现在假设我的 MyClass的&LT; T&GT; 具有支持通过自定义构造函数的IEqualityComparer&LT; T&GT; ,类似到 词典&LT; T&GT; 。在这种情况下,我需要做的...

Now suppose my MyClass<T> has a constructor that supports passing a custom IEqualityComparer<T>, similar to Dictionary<T>. In that case I'd need to do ...

private IEqualityComparer<T> _comparer;
public MyClass() {}
public MyClass(IEqualityComparer<T> comparer)
{
  _comparer = comparer;
}
void DoSomething(T o1, T o2)
{
  if((_comparer != null && _comparer.Equals(o1, o2)) || (o1.Equals(o2)))
  {
    ...
  }
}

要删除这个漫长的if语句,这会是一件好事,如果我能有 _comparer 默认为默认的比较如果经常构造函数。我搜索了类似的typeof(T).GetDefaultComparer()但无法找到这样的事情。

To remove this lengthy if statement, it'd be good if I could have _comparer default to a 'default comparer' if the regular constructor is used. I searched for something like typeof(T).GetDefaultComparer() but wasn't able to find anything like it.

我没有找到<一href="http://msdn.microsoft.com/en-us/library/ms224763.aspx"><$c$c>EqualityComparer<T>.Default,我可以使用吗?而随后将这个片段...

I did find EqualityComparer<T>.Default, could I use that? And would then this snippet ...

public MyClass()
{
  _comparer = EqualityComparer<T>.Default;
}
void DoSomething(T o1, T o2)
{
  if(_comparer.Equals(o1, o2))
  {
    ...
  }
}

...提供相同的结果与使用 o1.Equals(O2)所有可能的情况下?

... provide the same results as using o1.Equals(o2) for all possible cases?

(作为一个方面说明,就意味着我还需要使用任何特殊的通用约束&LT; T&GT;

(As a side note, would this mean I'd also need to use any special generic constraint for <T>?)

推荐答案

这应该是相同的,但它不能保证,因为它依赖于类型的实现细节 T 。照片 说明:
如果没有约束 T ,o1.Equals(O2)将调用的Object.Equals ,即使 T 工具 IEquatable&LT; T&GT;
EqualityComparer&LT; T&GT; .DEFAULT 然而,将使用的Object.Equals 只,如果 T 不执行 IEquatable&LT; T&GT; 。如果它的确实的实现该接口,它使用 IEquatable&LT; T&GT;。.Equals
只要 T 的实施的Object.Equals 只是调用 IEquatable&LT; T&取代。等于的结果是一样的。但在下面的例子中,结果是不相同的:

It should be the same, but it is not guaranteed, because it depends on implementation details of the type T.
Explanation:
Without a constraint to T, o1.Equals(o2) will call Object.Equals, even if T implements IEquatable<T>.
EqualityComparer<T>.Default however, will use Object.Equals only, if T doesn't implement IEquatable<T>. If it does implement that interface, it uses IEquatable<T>.Equals.
As long as T's implementation of Object.Equals just calls IEquatable<T>.Equals the result is the same. But in the following example, the result is not the same:

public class MyObject : IEquatable<MyObject>
{
    public int ID {get;set;}
    public string Name {get;set;}

    public override bool Equals(object o)
    {
        var other = o as MyObject;
        return other == null ? false : other.ID == ID;
    }    

    public bool Equals(MyObject o)
    {
        return o.Name == Name;
    } 
}

现在,它没有任何意义,实现一个这样的类。但是,你有同样的问题,如果为MyObject 的实施者只是忘了覆盖的Object.Equals

Now, it doesn't make any sense to implement a class like this. But you will have the same problem, if the implementer of MyObject simply forgot to override Object.Equals.

结论:
使用 EqualityComparer&LT; T&GT; .DEFAULT 是一个很好的路要走,因为你并不需要支持马车对象

Conclusion:
Using EqualityComparer<T>.Default is a good way to go, because you don't need to support buggy objects!

这篇关于EqualityComparer&LT; T&GT; .DEFAULT与T.Equals的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆