我想要一个继承自A< char >的便利包装器B.并实现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&lt; char [] &gt;和IEnumerable&lt; string &gt;并且它可能无法弄清楚我想要调用哪一个,但为什么它在“foreach”样本中工作正常?
请不要建议我通过作文来解决我的问题 - 这是我的最后手段。
答案 0 :(得分:2)
foreach
循环不使用IEnumerable
或IEnumerable<T>
实现。即使您的班级没有实施任何一个,您也可以使用foreach
。它唯一需要的是GetEnumerator
方法,它返回IEnumerator
实现。
请检查此问题:How is foreach implemented in C#?
这就是为什么您的班级使用foreach
而不使用ToArray()
。
答案 1 :(得分:2)
不同之处如下:
foreach
实际上会查找名为GetEnumerator
的公共方法。它并不真正关心IEnumerable<T>
。您的班级B
只有一个名为GetEnumerator
的公共方法:B
中定义的隐藏 A
中定义的方法。
ToArray
是IEnumerable<T>
上的扩展方法。由于您的班级同时为IEnumerable<string>
和IEnumerable<char[]>
,因此两个通用参数string
和char[]
之间的调用不明确。