在.NET中有任何类型的“ReferenceComparer”吗?

时间:2011-02-04 18:01:19

标签: c# .net comparison base-class-library

BCL中有几个地方可以使用IEqualityComparer。与Enumerable.ContainsDictionary Constructor一样。如果我对default不满意,我可以提供我的比较器。

有时我想知道该集合是否包含我引用的那个对象。不是任何其他意义上被认为是“平等”的那个 问题是: BCL中是否存在仅依赖ReferenceEquals方法的标准相等比较器?

我自己写的是:

class ReferenceComparer<T> : IEqualityComparer<T> where T : class
{
    private static ReferenceComparer<T> m_instance;

    public static ReferenceComparer<T> Instance
    {
        get
        {
            return m_instance ?? (m_instance = new ReferenceComparer<T>());
        }
    }

    public bool Equals(T x, T y)
    {
        return ReferenceEquals(x, y);
    }

    public int GetHashCode(T obj)
    {
        return RuntimeHelpers.GetHashCode(obj);
    }
}

我没有彻底测试它,也没有考虑很多场景,但似乎让Enumerable.ContainsDictionary非常高兴。

2 个答案:

答案 0 :(得分:17)

据我所知,自.NET 4.0起,BCL不会公开任何实现IEqualityComparer<T>引用相等的公共类型。

但是,似乎有许多内部类型可以执行此操作,例如:

  • System.Dynamic.Utils.ReferenceEqualityComparer<T> (在System.Core中)
  • System.Xaml.Schema.ReferenceEqualityComparer<T> (在System.Xaml中)。

我用反射器看了这两种类型的实现,你会很高兴知道这两种类型的实现方式实际上与你的相同,除了它们不对静态实例使用延迟初始化(它们在类型的静态构造函数中创建它)。

我能用你的实现想到的唯一可能的“问题”是懒惰初始化不是线程安全的,但由于实例是“便宜的”并且没有保持任何状态,所以不应该创建任何状态错误或主要性能问题。如果你想强制执行单例模式,你必须正确地进行。

答案 1 :(得分:2)

我最终也使用此解决方案,因为我找不到任何解决方法。

要修复非线程安全实现,您可以轻松使用静态初始化器。

public static ReferenceComparer<T> Instance => new ReferenceComparer<T>();

(抱歉答案而不是对投票通知的评论,我有一个没有评论权的新帐户)。