c# - 具有由 lambda 定义的自定义 IEqualityCompare 的 HashSet 构造函数?

标签 c# .net lambda iequalitycomparer

当前 HashSet<T>允许您自己定义相等比较的构造函数是 HashSet<T>(IEqualityComparer<T> comparer)构造函数。 我想将此 EqualityComparer 定义为 lambda。

我找到了 this blog post它创建了一个类,允许您通过 lambda 生成比较器,然后使用扩展方法隐藏此类的构造,例如执行 Except()。

现在我想做同样的事情,但要使用构造函数。是否可以通过扩展方法创建构造函数?或者有另一种方法我可以以某种方式创建一个 HashSet<T>(Func<T,T,int> comparer)

--更新--
为清楚起见,这是我要完成的内容的(片段)手绘版本:

HashSet<FileInfo> resultFiles = new HashSet<FileInfo>(
    srcPath.GetFiles(),
    new LambdaComparer<FileInfo>(
        (f1, f2) => f1.Name.SubString(10).Equals(f2.Name.SubString(10))));

或者更理想的

HashSet<FileInfo> resultFiles = new HashSet<FileInfo>(
    srcPath.GetFiles(),
    (f1, f2) => f1.Name.SubString(10).Equals(f2.Name.SubString(10)));

最佳答案

不,您不能添加构造函数(即使使用扩展方法)。

假设您有一些神奇的方法可以从 Func<T,T,int>IEqualityComparer<T> (如果您可以引用,我有兴趣阅读该博客文章)-那么您可以做的最接近的事情可能是:

public static class HashSet {
    public static HashSet<T> Create<T>(Func<T, T, int> func) {
        IEqualityComparer<T> comparer = YourMagicFunction(func);
        return new HashSet<T>(comparer);
    }
}

但是;我怀疑你可以用 lambda 做什么来实现平等......你有两个概念要表达:散列和真正的平等。你的 lambda 会是什么样子?如果您正在尝试推迟到子属性,那么可能是 Func<T,TValue>选择属性,并使用 EqualityComparer<TValue>.Default在内部……类似于:

class Person {
    public string Name { get; set; }
    static void Main() {
        HashSet<Person> people = HashSetHelper<Person>.Create(p => p.Name);
        people.Add(new Person { Name = "Fred" });
        people.Add(new Person { Name = "Jo" });
        people.Add(new Person { Name = "Fred" });
        Console.WriteLine(people.Count);
    }
}
public static class HashSetHelper<T> {
    class Wrapper<TValue> : IEqualityComparer<T> {
        private readonly Func<T, TValue> func;
        private readonly IEqualityComparer<TValue> comparer;
        public Wrapper(Func<T, TValue> func,
            IEqualityComparer<TValue> comparer) {
            this.func = func;
            this.comparer = comparer ?? EqualityComparer<TValue>.Default;
        }
        public bool Equals(T x, T y) {
            return comparer.Equals(func(x), func(y));
        }

        public int GetHashCode(T obj) {
            return comparer.GetHashCode(func(obj));
        }
    }
    public static HashSet<T> Create<TValue>(Func<T, TValue> func) {
        return new HashSet<T>(new Wrapper<TValue>(func, null));
    }
    public static HashSet<T> Create<TValue>(Func<T, TValue> func,
        IEqualityComparer<TValue> comparer)
    {
        return new HashSet<T>(new Wrapper<TValue>(func, comparer));
    }
}

关于c# - 具有由 lambda 定义的自定义 IEqualityCompare 的 HashSet 构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/881438/

相关文章:

typescript - typescript 中的lambda表达式类型

c# - 学习 Rx : How to use . 扫描 .Window 的输出以获取可观察的 bool 值序列

c# - 嵌套的 Linq Min() 使 Visual Studio 崩溃

.net - 制作内存密集型后台应用程序 "friendly"

c# - 如何转换表达式树?

c# - 为什么匿名方法不能赋值给var?

c# - 在不同的 DbContext 实例上重新执行 IQueryable?

c# - 无法注销 Azure Rms 移动服务用户

.net - 匹配不包含某个字符序列的字符串

c# - C# 默认位置中的配置文件?