我正在培训初学者的一些核心概念的过程中的C#。在创建一个IEnumerable的随机数字在他的代码中的错误提示投IEnumerable<T>
到IEnumerator<T>
什么演员IEnumerable <T> IEnumerator <T>做
我知道,不管这些接口的实现彼此什么我吃惊的是,无论是ReSharper的,也不是编译器和运行时抛出异常。
下面是一些示例代码:
public class SomeEnumerable : IEnumerable<int>
{
private readonly IEnumerable<int> _numbers;
public SomeEnumerable()
{
_numbers = Enumerable.Range(0,10);
}
public IEnumerator<int> GetEnumerator()
{
return (IEnumerator<int>) _numbers;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
不料GetEnumerator
- 方法编译完全正常。当初学者误将私人领域“_数字”ReSharper甚至建议添加我包括的显式演员。
现在考虑下面的测试代码:
var someEnumerable = new SomeEnumerable();
Console.WriteLine($"Number of elements: {someEnumerable.Count()}");
的Count()
- 方法调用枚举和输出是这样的:
Number of elements: 0
奇怪的是,如果你改变类的构造函数,以便它使用IList<T>
作为私人领域
public SomeEnumerable()
{
_numbers = Enumerable.Range(0,10).ToArray();
}
代码将引发适当的InvalidCastException。
我知道Enumerable.Range()
在其实现中使用yield
语句,并且编译器只要实现了GetEnumerator
方法就可以实现一些魔法,所以也许这是一个提示。
因此,我的问题是:
- 为什么剧组法律和为什么没有一个警告? (编译时间/ ReSharper的)
- 为什么你可以施放
IEnumerable
到IEnumerator
但不是一个IList
到IEnumerator
没有得到一个警告(ReSharper的) - 为什么伯爵调用的GetEnumerator /的foreach /等。产生一个空的结果?
- 如果有很好的理由使这个工作,框架的哪个部分使用它?
一些澄清: 我知道这不应该这样做,我知道它不能这样工作。但我感兴趣的,为什么代码产生IL被编译并执行完美的罚款,但单产这种奇怪的结果
这留下了一些未解答的问题。哪个类不指望我把它转换为另一种类型,为什么这个类会使用这两个接口? –
@JanWolf您正在投射到'IEnumerator'的类。如果你想知道为什么设计课程的人按照他们的方式设计的,你可以问他们。我们只能猜测他们为什么选择按照他们的方式来设计课堂。 –
Servy
我会对细节感兴趣。我知道如何正确地做,这不是问题,我知道它不应该工作,这不是问题。问题是为什么它工作(为什么这个类实现两个接口),结果的枚举器做什么(什么是正在返回的枚举器) 我知道这是不正确的代码 –