c# – 向IEnumerator投射IEnumerable做什么

c# – 向IEnumerator投射IEnumerable做什么,第1张

概述我正在培训初学者一些C#的核心概念.在为随机数创建IEnumerable时,他的代码中的错误建议投射IEnumerable< T>.到IEnumerator< T> 我知道这些接口都没有相互实现,所以令我印象深刻的是ReSharper,编译器和运行时都没有引发异常. 这是一些示例代码: public class SomeEnumerable : IEnumerable<int>{ pri 我正在培训初学者一些C#的核心概念.在为随机数创建IEnumerable时,他的代码中的错误建议投射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-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做什么所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1220323.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存