多个IEnumerable实现悖论

本文关键字:实现 IEnumerable 多个 | 更新日期: 2023-09-27 18:22:24

  1. 我有一个通用类a<T>,实现IEnumerable<T[]>
  2. 我想要一个从a<char>并实现IEnumerable<string>。

    public class A<T> : IEnumerable<T[]>
    {
        public IEnumerator<T[]> GetEnumerator()
        {
            return Enumerate().GetEnumerator();
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        protected IEnumerable<T[]> Enumerate()
        {
            throw new System.NotImplementedException();
        }
    }
    public class B : A<char>, IEnumerable<string>
    {
        public IEnumerator<string> GetEnumerator()
        {
            return Enumerate().Select(s => new string(s)).GetEnumerator();
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
    

现在,这非常好,foreach变量类型被推断为字符串:

B b = new B();
foreach (var s in b)
{
    string[] split = s.Split(' ');
}

但这不会编译,说"类型参数不能从用法中推断出来,请尝试显式指定类型参数":

string[] strings = b.ToArray();

然而,这是有效的:

string[] strings = b.ToArray<string>();

有人能解释编译器的这种行为吗?

显然,B实现了IEnumerable<char[]>和IEnumerable<string>,可能它不知道我想调用其中的哪一个,但为什么它在"foreach"示例中工作良好?

请不要建议我通过作文来解决我的问题——这是我的最后手段。

多个IEnumerable实现悖论

区别如下:

foreach实际上在寻找一个名为GetEnumerator的公共方法。它实际上并不关心IEnumerable<T>。类B只有一个名为GetEnumerator的公共方法:在B中定义的方法,隐藏A中定义的。

CCD_ 8是对CCD_。由于您的类既是IEnumerable<string>又是IEnumerable<char[]>,因此调用在两个泛型参数stringchar[]之间是不明确的。

foreach循环不使用IEnumerableIEnumerable<T>实现。您可以使用foreach,即使您的类没有实现它们中的任何一个。它唯一需要的是返回IEnumerator实现的GetEnumerator方法。

检查这个问题:foreach是如何在C#中实现的?

这就是为什么您的类使用foreach而不使用ToArray()