开发者

Using base.Any(..) the warning is: 'HashSet' does not contain a definition for 'Any'

开发者 https://www.devze.com 2023-01-18 04:28 出处:网络
A class inherits from HashSet to get a set of unique objects with custom EqualKeys(T x, T y) check instead of IEqualityComparer.

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.

I am afraid I don't understand why that is?


"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.

0

精彩评论

暂无评论...
验证码 换一张
取 消