C# 是否有任何形式的;“参考比较人”;在.NET中?

C# 是否有任何形式的;“参考比较人”;在.NET中?,c#,.net,comparison,base-class-library,C#,.net,Comparison,Base Class Library,在BCL中有几个地方可以利用。喜欢还是喜欢。如果我对比较器不满意,我可以提供我的比较器 有时我想知道集合是否包含我所引用的对象。不是在任何其他意义上被视为“平等”的人。 问题是:BCL中是否存在仅依赖于方法的标准等式比较器? 我自己写的是: class ReferenceComparer<T> : IEqualityComparer<T> where T : class { private static ReferenceComparer<T> m_i

在BCL中有几个地方可以利用。喜欢还是喜欢。如果我对比较器不满意,我可以提供我的比较器

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

我自己写的是:

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);
    }
}
class ReferenceComparer:IEqualityComparer其中T:class
{
私有静态引用比较程序m_实例;
公共静态引用比较程序实例
{
得到
{
返回m_实例??(m_实例=new ReferenceComparer());
}
}
公共布尔等于(TX,TY)
{
返回引用等于(x,y);
}
公共int GetHashCode(T obj)
{
返回RuntimeHelpers.GetHashCode(obj);
}
}

我没有彻底测试它,也没有考虑很多场景,但它似乎使
可枚举。包含
字典
非常愉快。

据我所知,BCL没有公开任何实现
IEqualityComparer
的公共类型,从.NET 4.0起具有引用平等性

但是,似乎确实有一系列内部类型可以做到这一点,例如:

  • System.Dynamic.Utils.ReferenceEqualityComparer
    (在System.Core中)
  • System.Xaml.Schema.ReferenceEqualityComparer
    (在System.Xaml中)
我使用reflector查看了这两种类型的实现,您会很高兴知道它们的实现方式与您的实现方式几乎相同,只是它们不使用静态实例的延迟初始化(它们在类型的静态构造函数中创建)


我能想到的实现中唯一可能的“问题”是延迟初始化不是线程安全的,但由于实例“便宜”且不保持任何状态,因此不应产生任何bug或重大性能问题。但是,如果您想强制执行单例模式,您必须正确地执行。

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

要修复非线程安全的实现,可以轻松使用静态initiailizer

public static ReferenceComparer<T> Instance => new ReferenceComparer<T>();
publicstaticreferencecomparer实例=>newreferencecomparer();

(很抱歉回答这个问题,而不是向上投票的线程添加注释,我有一个没有注释权限的新帐户)。

不幸的是,所有这些集合都是以Java风格的方式编写的,需要您编写一个实现特定接口的类。如果它们只允许您传入一个委托以指定比较运算符,则可以直接传递
object.ReferenceEquals
。我想这是因为需要两种方法(比较法和hashcode)。但据我所知,
IEqualityComparer
的Java对应物没有
GetHashCode
,因此如果Java支持委托,它可以在Java中实现为委托。@Ben看一下orip的回答:@Hellfrost:great link。遗憾的是,这些都没有包含在.NET中。另请参见:感谢您提到我的延迟初始化失败。对于这个类,在静态构造函数中初始化实例看起来很有意义。不过,多亏了你,我在其他任何地方都不会犯同样的错误。@alpha-mouse:干杯。我要说的是,我不会觉得仅仅为了类线程而有义务使其安全,除非我打算以需要的方式使用它。还有
System.Data.Entity.Infrastructure.ObjectReferenceEqualityComparer
namespace System.Dynamic.Utils{内部密封类引用EqualityComparer{…}
内部
禁止我们直接使用,
密封
也禁止任何间接使用:-(