Dan*_*ker 90 c# exception yield-keyword
以下是可以的:
try
{
Console.WriteLine("Before");
yield return 1;
Console.WriteLine("After");
}
finally
{
Console.WriteLine("Done");
}
Run Code Online (Sandbox Code Playgroud)
该finally
块在整个执行完毕后运行(IEnumerator<T>
支持IDisposable
提供一种方法来确保即使枚举在完成之前被放弃).
但这不是好事:
try
{
Console.WriteLine("Before");
yield return 1; // error CS1626: Cannot yield a value in the body of a try block with a catch clause
Console.WriteLine("After");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Run Code Online (Sandbox Code Playgroud)
假设(为了参数)WriteLine
try块中的一个或另一个调用抛出异常.在catch
块中继续执行有什么问题?
当然,收益率回报部分(目前)无法抛出任何东西,但是为什么要阻止我们封闭try
/ catch
处理在之前或之后抛出的异常yield return
?
更新:Eric Lippert在这里有一个有趣的评论 - 似乎他们已经有足够的问题正确实现try/finally行为!
编辑:此错误的MSDN页面是:http://msdn.microsoft.com/en-us/library/cs1x15az.aspx.但这并没有解释为什么.
Jon*_*eet 48
我怀疑这是一个实用性而非可行性的问题.我怀疑很少有这种限制实际上是一个无法解决的问题 - 但编译器中增加的复杂性将非常重要.
我已经遇到过这样的一些事情:
在每种情况下,都有可能获得更多的自由,代价是编译器的额外复杂性.团队做出了务实的选择,我为此鼓掌 - 我宁愿用一种稍微限制一点的语言,准确率达到99.9%的编译器(是的,有错误;我在前几天碰到了一个)而不是更多灵活的语言,无法正确编译.
编辑:这是一个伪证明它为什么可行的原因.
考虑一下:
现在变换:
try
{
Console.WriteLine("a");
yield return 10;
Console.WriteLine("b");
}
catch (Something e)
{
Console.WriteLine("Catch block");
}
Console.WriteLine("Post");
Run Code Online (Sandbox Code Playgroud)
进入(有点伪代码):
case just_before_try_state:
try
{
Console.WriteLine("a");
}
catch (Something e)
{
CatchBlock();
goto case post;
}
__current = 10;
return true;
case just_after_yield_return:
try
{
Console.WriteLine("b");
}
catch (Something e)
{
CatchBlock();
}
goto case post;
case post;
Console.WriteLine("Post");
void CatchBlock()
{
Console.WriteLine("Catch block");
}
Run Code Online (Sandbox Code Playgroud)
唯一的重复是设置try/catch块 - 但这是编译器当然可以做的事情.
我可能在这里错过了一些东西 - 如果有的话,请告诉我!
yield
迭代器定义中的所有语句都转换为状态机中的状态,该状态机有效地使用switch
语句来推进状态.如果它确实为yield
try/catch中的语句生成代码,则必须为每个语句复制块中的所有内容,同时排除该try
块的每个 yield
其他yield
语句.这并不总是可行的,特别是如果一个yield
语句依赖于前一个语句.
归档时间: |
|
查看次数: |
24450 次 |
最近记录: |