产量/迭代器角落的情况下

在这篇文章中(http://blogs.msdn.com/oldnewthing/archive/2008/08/13/8854601.aspx),有一个关于迭代器和一个关于一个角落的情况下弹出的问题:

练习:请考虑下面的代码片段:的foreach(诠释我在CountTo100Twice()){...}

说明在对MoveNext的第150个电话()在上面的循环会发生什么。 讨论其后果递归枚举(如树的遍历)。

我还没有运行该代码,但我假设,这是一个问题,据称与文章(以下提供的所有链接)的答案,但我无法找到的文章或评论共享知识的答案针对这种特殊商品。

没有人知道答案是什么? 还有哪些其他的情况有哪些?

1)http://blogs.msdn.com/oldnewthing/archive/2008/08/12/8849519.aspx

2)http://blogs.msdn.com/oldnewthing/archive/2008/08/13/8854601.aspx

3)http://blogs.msdn.com/oldnewthing/archive/2008/08/14/8862242.aspx

4)http://blogs.msdn.com/oldnewthing/archive/2008/08/15/8868267.aspx

谢谢

--------------解决方案-------------

我怀疑他可能是指一个事实,即每次调用MoveNext()调用一个状态机,从而调用MoveNext()上的另一状态机,使得这一切有点效率低下。

这是博客上讲述这里由韦斯·代尔在这里通过埃里克利珀。

主要的角落情况下,我会说有迭代器块是没有什么是第一次调用之前执行到MoveNext() 所以这个方法:

public IEnumerable<string> ReadLines(string file)
{
if (file == null)
{
throw new ArgumentNullException("file");
}
using (TextReader reader = File.OpenText(file))
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}

直到你开始迭代实际上并不抛出异常。 相反,你需要这样写:

public static IEnumerable<string> ReadLines(string file)
{
if (file == null)
{
throw new ArgumentNullException("file");
}
return ReadLinesImpl(file);
}

public static IEnumerable<string> ReadLinesImpl(string file)
{
using (TextReader reader = File.OpenText(file))
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}

此外,埃里克已经在博客上这样的:第1,第2,我在博客中建议,以使生活更轻松过,但我怀疑它会永远来什么。

一些东西。

(1)乔恩当然是正确的; 问题是,嵌套迭代器一样,这给你的迭代器的逻辑调用堆栈。 如果你是一个迭代深递归定义的数据结构,这可以吹堆栈,并且有简便的方法来转一下应该是一个线性算法成二次算法。 见韦斯的更多细节的文章。

(2)我们可以建立一种新的迭代器的逻辑成没有性能问题的语言。 我很想实现这一点,但它不是一个足够高的优先权了。 如果你有兴趣在如何做到这一点的技术细节,请阅读本文。

(3)有许多其他的情况; 已经提到(延迟的边界检查和finally块的延迟执行执行)的那些是两种最常见的。 不幸的是,在C#的许多版本中有码发生器臭虫加剧后一个问题。 假设你有尝试{尝试{...屈服...}终于{X()}}终于{Y()} - 有怪异的情况下,你可以进入我们产生码X之前不小心调用Y() ()清理道路,这显然是错误的。 我们已经解决了这些的服务包,但如果你发现其他人,请让我知道。

(4)也有做这样一个产量突破了最后,然后分支到外部最终它做了第二个冗余产量突破疯狂的事情,当涉及到迭代器的确切行为的一些现存的非常模糊的错误。 同样,如果你碰巧发现怪异,行为迭代,随时给他们带来了我的注意。

当你考虑一个有趣的角落情况下与产量/迭代器发生try..finally衍生usinglock语句。 考虑迭代器块乔恩斯基特上面贴:

public IEnumerable<string> ReadLines(string file)
{
if (file == null)
{
throw new ArgumentNullException("file");
}
using (TextReader reader = File.OpenText(file))
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}

如果你使用这个迭代器块的上下文之外foreach调用MoveNext()手动几次你永远不完成迭代,会发生什么情况该using ? 答: finally的部分using从未被调用,从而从来没有要求DisposeTextReader永不关闭打开的文件。 同样的,想象的using换成了lock(something)finally所述的部分lock将永远不会被调用从未释放对象的锁。

教训 :一定要避免使用try..finally和它的衍生物在迭代器块。

分类:C# 时间:2012-01-01 人气:0
本文关键词: C#
分享到:

相关文章

  • 在C#中扩展枚举 2012-01-01

    我想知道我是否可以延长枚举类型在C#来实现我的自定义Enum.GetValues​​(型),并调用它像Enum.GetMyCustomValues​​(类型) 我想实现这样的事情: public static bool IsFlagSet<T>(this T value, T flag) where T : Enum { return (value & flag) != (T)0; } 但它不能这样做......任何变通我能做什么? 干杯 --------------解决方案-----

  • PHP客户端和C#服务器 - 不沟通,由于超时 2012-01-01

    我是相当新的Socket编程,但这里不用什么. 我一直试图做一个C#服务器和PHP客户端之间的一些简单的TCP通信. 不过,我曾在让他们之间的连接没有运气. 我基本上经由PHP socket通信的Web浏览器发送一个桌面应用程序的消息. 不过,我不断收到超时错误. 我的代码如下: 我的C#代码服务器-它只是简单地聆听,并通知我,如果建立连接 static void Main(string[] args) { try { IPAddress localAddress = IPAddress.Par

  • C#如何获得元素的宽度 2012-01-01

    有没有一种方法,我可以做jQuery的的equivilant var myElementWidth = $('.class').width; 在C#和存储它作为一个变量,以备后用. 任何指针将受到欢迎. --------------解决方案------------- 正如一些评论指向,如果位置和大小的客户端,C#情况,服务器端代码永远不会知道一些特定元素的实际尺寸和位置. 但是,如果这是宽为Web应用程序非常重要,也许你可以设置客户端呈现一些异步操作页面只是在此之后的价值. 我要说的是,这样做的

  • 如何关闭*多显示*在C#? 2012-01-01

    有关于"如何关闭监视器在C#"的文章很多,但他们都关掉所有的监视器. 有没有关闭特定监视器任何可能的方式? --------------解决方案------------- 研究一点点导致我在这里: http://www.codeguru.com/forum/showthread.php?p=1011720#post1011720 你知道如何调用一个函数一样,在C#中? - 编辑 貌似这家伙所做的这一切为你: http://www.codeproject.com/KB/dotnet/Di

  • 如何包装无的WinForms的DataGridViewTextBoxCell(C#),空格或换行符长文本? 2012-01-01

    如何包装无空格或换行符长文本DataGridViewTextBoxCell的WinForms的(C#)? private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) { if ((e.ColumnIndex == 1) && (e.FormattedValue != null)) { SizeF sizeGraph = e.Graphics.MeasureString

  • 基于常数值强制C#编译器错误 2012-01-01

    我有一个C#类中定义的私有const int的. 我想编译失败与错误,如果这个INT模3的值!= 0,我怎样才能做到这一点? --------------解决方案------------- 蒂莫西·扈利几乎得到了它. 它应该是这样的: int compilerError = 1 / (MY_CONST % 3 == 0 ? 1 : 0); 虽然产生编译时错误的#ERROR预处理器指令,也没有办法为它基于对一个const值的存在. 只带编译符号的作品,如"DEBUG",为它的值不能进行分

  • 用C#模仿批处理文件 2012-01-01

    我有一个运行四个命令的批处理文件 vsinstr -coverage hello.exe vsperfcmd /start:coverage /output:run.coverage hello vsperfcmd /shutdown 如何使用C#来运行四个命令? --------------解决方案------------- 运行使用的Process.Start的命令. 例 使用覆盖Process.Start(string fileName, string arguments) Process

  • 无法在F#扩展运营商? 2012-01-01

    module FSharp= let Point2d (x,y)= Point2d(x,y) let Point3d (x,y,z)= Point3d(x,y,z) type NXOpen.Point3d with static member ( * ) (p:Point3d,t:float)= Point3d(pX*t,pY*t,pZ*t) static member ( * ) (t:float,p:Point3d)= Point3d(pX*t,pY*t,pZ*t) static membe

  • 如何通过C#中添加自定义的控制,我们的表格 2012-01-01

    我使用Visual Studio 2008(WPF / C#). 我创建了一个自定义的控制,并将其添加为我的项目的引用. 现在我想动态添加通过代码背后(C#),即自定义控件. 任何人都帮我出的这些. --------------解决方案------------- 这是,你可以通过一些谷歌上搜索发现动辄基本的东西. 不管怎么说参考http://arcanecode.com/2007/09/07/adding-wpf-controls-progrrammatically/这link..it 5可以帮

  • 什么办法让一个BITMAPV5HEADER在C#中的位图对象 2012-01-01

    有没有什么办法让一个BITMAPV5HEADER在C#中的位图对象? 或者只是得到了在他们的价值观? 我需要得到一些ColorSpace中的信息进行位图,并不能看到一个办法做到这一点在C#. --------------解决方案------------- 似乎没有成为一个简单的方法来做到这一点,但hackish的(也可能是非常错误的)方法是将读取原始数据,并将其转换为一个BITMAPV5HEADER结构. 结构体 [StructLayout(LayoutKind.Sequential)] pub

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.256 (s). 10 q(s)