score:2

Accepted answer

That's because DerivedEnumerator implements both IEnumerable<BaseThingy> and IEnumerable<DerivedThingy> (indirectly via IReadOnlyColleciton). So when you do

var y = derivedEnumerator.Where(s => s.GetHashCode() == s.GetHashCode());

Compiler cannot figure out what is the type of s in lamdba. Is that DerivedThingy? Is that BaseThingy? Both are possible. So you need to tell it explicitly what that is:

var y = derivedEnumerator.Where<DerivedThingy>(s => s.GetHashCode() == s.GetHashCode());

or

var y = derivedEnumerator.Where((DerivedThingy s) => s.GetHashCode() == s.GetHashCode());

That said, it's quite unusual design and you might reconsider it. How exactly depends on what you are trying to do (so, why do you need to inherit enumerators this way).

score:0

Ambiguity issue

namespace ClassLibrary1
{
    public class BaseThingy { }

    public class DerivedThingy : BaseThingy { }

    public class BaseEnumerator : IReadOnlyCollection<BaseThingy>
    {
        public int Count => throw new NotImplementedException();

        public IEnumerator<BaseThingy> GetEnumerator()
        {
            throw new NotImplementedException();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }
    }

    public class DerivedEnumerator : BaseEnumerator, IReadOnlyCollection<DerivedThingy>
    {
        IEnumerator<DerivedThingy> IEnumerable<DerivedThingy>.GetEnumerator()
        {
            throw new NotImplementedException();
        }
    }

    public class Application
    {
        public void Main()
        {
            BaseEnumerator baseEnumerator = new BaseEnumerator();
            DerivedEnumerator derivedEnumerator = new DerivedEnumerator();

            // Works...
            var x = baseEnumerator.Where(s => s.GetHashCode() == s.GetHashCode());

            // Works now
            var y = derivedEnumerator.Where<DerivedThingy>(s => s.GetHashCode() == s.GetHashCode());
        }
    }
}

Related Articles