No, you cannot add constructors (even using extension methods).
Assuming you have some kind of magical way to get from Func<T,T,int> to IEqualityComparer<T> (I would be interested to read this blog post if you can quote it) - then the closest thing you can probably do something like:
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); } }
Nonetheless; I doubt what you can do with lambda for equality ... you have two concepts to express: hashing and true equality. What would your lambda look like? If you are trying to defer child properties, then maybe Func<T,TValue> to select a property, and use EqualityComparer<TValue>.Default internally ... something like:
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)); } }
source share