我知道这些接口都没有相互实现,所以令我印象深刻的是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-Method编译得非常好.当初学者错误地将私人字段“_numbers”放入时,ReSharper甚至建议添加我已包含的显式演员.
现在考虑以下测试代码:
var someEnumerable = new SomeEnumerable();Console.Writeline($"Number of elements: {someEnumerable.Count()}");
Count() – Method调用枚举器,输出如下:
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)
>为什么通过Count / foreach / etc调用GetEnumerator.产生空结果?
>如果有充分理由这样做,框架的哪一部分可以利用它?
一些澄清:
我知道不应该这样做,我知道它永远不会以这种方式工作.但我感兴趣的是为什么代码导致IL编译和执行完全正常但产生如此奇怪的结果
Why is the cast legal and why isn’t there a warning?
演员的全部意义在于你告诉编译器,“我知道你不认为这种类型实际上是另一种类型,但我比你知道更多,让我把它看作是这个其他类型如果我错了,在运行时抛出异常.
Why can you cast an IEnumerable to an IEnumerator but not an IList to an IEnumerator without getting a warning (ReSharper)
你不能投出任何IEnumerable< T>到IEnumerator< T>.这个特定对象恰好实现了两个接口.其他对象,例如你编写的SomeEnumerable,只会实现其中一个,而像这样的强制转换对它们来说会失败(在运行时).
Why does invoking GetEnumerator by Count/foreach/etc. yIEld an empty result?
该对象不期望您将其转换为另一种类型并开始在其上调用方法.你违反了合同类型.如果你想让它正常工作,请调用GetEnumerator,它会为你提供一个合适的枚举器.实际上,由于您破坏了初始化其数据的方法,因此您将获得一个未正确初始化的枚举器.
If there is a good reason for this to work,which part of the framework makes use of that?
它只是一个看起来像这样的类型:
public class SomeClass: IEnumerable<int>,IEnumerator<int>{ //...}
如果你愿意,你可以写一个这样的类.
总结以上是内存溢出为你收集整理的c# – 向IEnumerator投射IEnumerable做什么全部内容,希望文章能够帮你解决c# – 向IEnumerator投射IEnumerable做什么所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)