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

Bor*_*ens 5 .net c# lambda iequalitycomparer

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

我发现这个博客帖子已经创建了一个类,允许你通过lambda生成你的比较器,然后使用extention方法隐藏这个类的构造,例如一个Except().

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

--UPDATE--
为了清楚起见,这是我所要完成的徒手版本的一个片段:

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

或更理想的

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

Mar*_*ell 5

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

假设你有一些神奇的方法可以从a Func<T,T,int>到a 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然而; 我怀疑你能用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));
    }
}
Run Code Online (Sandbox Code Playgroud)