C# IEnumerable的非泛型版本是否支持延迟执行?

C# IEnumerable的非泛型版本是否支持延迟执行?,c#,ienumerable,deferred-execution,C#,Ienumerable,Deferred Execution,如果是,它在哪些.NET Framework版本上受支持 我已在.NET Framework 4.0上对此进行了测试,效果良好: using System; using System.Collections.Generic; public class TestClass { public IEnumerable Defer() { yield return 1; yield return 2; yield return 3;

如果是,它在哪些.NET Framework版本上受支持

我已在.NET Framework 4.0上对此进行了测试,效果良好:

using System;
using System.Collections.Generic;

public class TestClass
{
    public IEnumerable Defer()
    {
        yield return 1;
        yield return 2;
        yield return 3;
    }
}

是的,自从使用
yield
关键字以来,它就一直受到支持。唯一的区别是,它或多或少是
IEnumerable
,如果必须执行装箱操作,可能会导致效率低下。除此之外,它完全是一样的。

因为
的yield
关键字被简化为编译器的诡计,想必这应该是可行的。它当然适用于2.0运行时;但是,我不想对1.1做任何声明。

非泛型IEnumerable没有实现IDisposable。当使用不支持IEnumerable(Of T)的枚举数时,VB.Net和C#可能会使用IDisposable或.Dispose()方法来duck type,但肯定不能依赖非泛型IEnumerable的所有使用者来实现。如果枚举的使用者没有正确地执行.Dispose(),则枚举数的执行(包括显式或隐式finally子句)将被放弃。

延迟执行与
收益率无关。
<代码>产量只是语法糖。没有理由不能在.NET 1.0中使用
IEnumerable
.True延迟执行。但是,OP的例子特别使用了收益率,这表明他没有瞄准1.0。(这几天有人吗?)谢谢你提醒我,产量只是糖分。至于使用1.0,I agree迭代器(yield关键字)首先在VS2005附带的C#version 2中提供;我就是不能用IEnumerable来掩饰这个明显的设计缺陷。我正在阅读这篇文章,它在“向后兼容性”下指出,期望使用非泛型IEnumerator的客户端代码不会正确地处理迭代器。这会导致什么样的错误?@ TAMAMCGLN:考虑在多个线程中使用的集合的情况。如果枚举集合的所有代码都调用
GetEnumerator
,快速枚举集合,然后在该枚举器上调用
Dispose
,那么让
GetEnumerator
获取锁并让
Dispose
释放锁可能会很好。但是,如果从未调用
Dispose
,则需要使用集合的代码可能会被无限期阻止。我们可以通过让集合持有一个引用来解决这个问题,该引用将标识活动枚举器(如果存在),并拥有代码来……检查锁是否由枚举器持有,如果是,则先等待一段时间等待锁。如果失败,代码可能会启用一个次锁[枚举器每次实际获取元素时必须获取并释放该次锁],将集合的剩余部分枚举到列表中,告诉枚举器从该列表中获取剩余数据,然后窃取主锁。然而,这会增加很多复杂性,如果枚举器的用户遵守适当的规程,就不需要这样做。那么这是否意味着让IEnumerator继承IEnumerator违反了Liskov替换原则?当某个人在接口中指定接受所有IEnumerator时,您不能仅向其传递IEnumerator,因为这样这些接口就不会处理IEnumerator,这可能会导致您描述的锁定问题。@TamaMcGlinn:问题根本上是
IEnumerable。GetEnumerator
可能返回以下三种情况之一:“可以安全地放弃但未实现
IDisposable
”的对象、“只能调用
Dispose
”的对象,或“可以通过调用或不调用
Dispose
安全地放弃的对象”,客户端代码无法很好地处理这三个问题
IEnumerable
保证它不会返回第一种类型的对象。
IEnumerable
的原始设计者可能期望它永远不会返回第二种类型的对象,但这是不现实的。