C#:当派生类及其基类实现IEnumerable时,在派生迭代器类上使用LINQ

时间:2018-02-22 05:34:27

标签: c# linq inheritance ienumerable

我有一种情况,我有我得到的迭代器类。基础迭代器迭代基础对象,派生迭代器迭代通过派生对象。我可以在基础迭代器上使用LINQ,但不能在派生迭代器上使用LINQ。如果我可以使用LINQ迭代它将是非常有帮助的。

提前感谢任何指导!

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());

            // Doesn't work...
            var y = derivedEnumerator.Where(s => s.GetHashCode() == s.GetHashCode());
        }
    }
}

2 个答案:

答案 0 :(得分:2)

这是因为DerivedEnumerator实现IEnumerable<BaseThingy>IEnumerable<DerivedThingy>(间接通过IReadOnlyColleciton)。所以当你这样做时

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

编译器无法弄清楚lamdba中s的类型。那是DerivedThingy吗?那是BaseThingy吗?两者都有可能。所以你需要明确告诉它是什么:

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

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

那就是说,这是一个非常不寻常的设计,你可能会重新考虑它。究竟取决于你想要做什么(所以,为什么你需要以这种方式继承枚举器。)

答案 1 :(得分:0)

歧义问题

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());
        }
    }
}