首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >将委托包装在IEqualityComparer中

将委托包装在IEqualityComparer中
EN

Stack Overflow用户
提问于 2008-09-18 23:34:18
回答 11查看 47.6K关注 0票数 128

几个Linq.Enumerable函数都有一个IEqualityComparer<T>。有没有一个方便的包装类来适应实现IEqualityComparer<T>delegate(T,T)=>bool?编写一个很容易(如果您忽略了定义正确的哈希码的问题),但是我想知道是否有开箱即用的解决方案。

具体地说,我希望在Dictionary上执行集合操作,只使用键来定义成员身份(同时根据不同的规则保留值)。

EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2010-09-16 00:13:50

通常,我会通过在答案上评论@Sam来解决这个问题(我已经对原始帖子进行了一些编辑,以便在不改变行为的情况下对其进行一些清理。)

以下是我的@Sam's answer摘要,以及对默认散列策略的IMNSHO关键修复:

class FuncEqualityComparer<T> : IEqualityComparer<T>
{
    readonly Func<T, T, bool> _comparer;
    readonly Func<T, int> _hash;

    public FuncEqualityComparer( Func<T, T, bool> comparer )
        : this( comparer, t => 0 ) // NB Cannot assume anything about how e.g., t.GetHashCode() interacts with the comparer's behavior
    {
    }

    public FuncEqualityComparer( Func<T, T, bool> comparer, Func<T, int> hash )
    {
        _comparer = comparer;
        _hash = hash;
    }

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

    public int GetHashCode( T obj )
    {
        return _hash( obj );
    }
}
票数 46
EN

Stack Overflow用户

发布于 2009-08-06 14:41:24

当您想要自定义相等检查时,99%的时间您感兴趣的是定义要进行比较的键,而不是比较本身。

这可能是一个优雅的解决方案(来自Python的list sort method的概念)。

用法:

var foo = new List<string> { "abc", "de", "DE" };

// case-insensitive distinct
var distinct = foo.Distinct(new KeyEqualityComparer<string>( x => x.ToLower() ) );

KeyEqualityComparer类:

public class KeyEqualityComparer<T> : IEqualityComparer<T>
{
    private readonly Func<T, object> keyExtractor;

    public KeyEqualityComparer(Func<T,object> keyExtractor)
    {
        this.keyExtractor = keyExtractor;
    }

    public bool Equals(T x, T y)
    {
        return this.keyExtractor(x).Equals(this.keyExtractor(y));
    }

    public int GetHashCode(T obj)
    {
        return this.keyExtractor(obj).GetHashCode();
    }
}
票数 119
EN

Stack Overflow用户

发布于 2008-09-18 23:52:01

恐怕没有开箱即用的包装器。然而,创建一个并不难:

class Comparer<T>: IEqualityComparer<T>
{
    private readonly Func<T, T, bool> _comparer;

    public Comparer(Func<T, T, bool> comparer)
    {
        if (comparer == null)
            throw new ArgumentNullException("comparer");

        _comparer = comparer;
    }

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

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

...

Func<int, int, bool> f = (x, y) => x == y;
var comparer = new Comparer<int>(f);
Console.WriteLine(comparer.Equals(1, 1));
Console.WriteLine(comparer.Equals(1, 2));
票数 47
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/98033

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档