A class inherits from HashSet to get a set of unique objects with custom EqualKeys(T x, T y)
check instead of IEqualityComparer
.
public class UniqueSet<T> : HashSet开发者_如何学编程<T> where T : IKey
{
public new void Add(T item)
{
// .. check item for null, empty key etc.
if (base.Any(t => UniqueSet<T>.EqualKeys(t, item)))
{
throw new ArgumentException(..);
}
if (!base.Add(item)) throw new ArgumentException(..);
}
private static bool EqualKeys(T x, T y)
{
return ((IKey)x).Key.Equals(((IKey)y).Key, StringComparison.CurrentCultureIgnoreCase);
}
}
The code doesn't compile because I have to replace base.Any
with this.Any
.
"Any" is an extension method, not a method of HashSet<T>
. It doesn't exist on the base type, so you cannot invoke it explicitly on the base type. When you invoke it with "this.Any", the overload resolution code cannot find "Any" on the type of "this" so it starts looking for extension methods, and finds one.
Not your question, but I'll mention it anyway: why throw if you add to a set that already has such an element? Why not just make it a no-op to do so? By throwing you make it a requirement for the caller of Add to know whether the element is in the set already or not, which seems like an onerous requirement.
Because HashSet<T>
doesn't implement Any()
. Any()
is an Extension Method from IEnumerable<T>
. When you use base, you are explicitly referencing the base type and not its extension methods.
精彩评论