【问题标题】:Does the non-generic version of IEnumerable support deferred execution?IEnumerable 的非泛型版本是否支持延迟执行?
【发布时间】:2011-01-13 02:04:12
【问题描述】:

如果支持,它支持哪些 .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 关键字)首先在 C# 版本 2 中可用,随 VS2005 一起提供。

标签: c# ienumerable deferred-execution


【解决方案1】:

是的,从 yield 关键字开始就支持它。唯一的区别是它或多或少是IEnumerable<object>,如果它必须做拳击,这可能会导致效率低下。除此之外,完全一样。

【讨论】:

  • 延迟执行与yield无关。 yield 只是语法糖。没有理由不能在 .NET 1.0 中使用 IEnumerable 延迟执行。
  • 是的。但是,OP 的示例专门使用了 yield,这表明他的目标不是 1.0。 (现在有人吗?)
  • 感谢您提醒我 yield 只是语法糖。至于使用1.0,我同意
【解决方案2】:

由于yield 关键字被简化为编译器诡计,大概这应该有效。它当然适用于 2.0 运行时;不过,我会犹豫对 1.1 发表任何声明。

【讨论】:

    【解决方案3】:

    非泛型 IEnumerable 不实现 IDisposable。当使用不支持 IEnumerable(Of T) 的枚举器时,VB.Net 和 C# 可能会回避类型 IDisposable 或 .Dispose() 方法,但当然不能依赖非泛型的所有消费者IEnumerable 这样做。如果枚举的使用者没有正确地 .Dispose() 它,枚举器的执行,包括显式或隐式 finally 子句,将被放弃。

    【讨论】:

    • 我正在寻找这方面的更多信息;我无法用 IEnumerable 解决这个明显的设计缺陷。我正在阅读这篇文章codeproject.com/Articles/29534/…,它在“向后兼容性”下指出,期望非泛型 IEnumerator 的客户端代码没有正确处理迭代器。这会导致什么样的错误?
    • @TamaMcGlinn:考虑在多个线程中使用的集合的情况。如果枚举集合的所有代码都调用GetEnumerator,快速枚举集合,然后在该枚举器上调用Dispose,那么让GetEnumerator 获取锁并让Dispose 释放它可能会运行良好。但是,如果 Dispose 从未被调用,则需要使用该集合的代码可能会被无限期地阻塞。也许可以通过让集合持有一个引用来解决这个问题,该引用将识别活动的枚举器(如果存在的话),并且有代码......
    • ...检查锁是否被一个枚举器持有,如果是的话,先等待一会儿锁。如果失败,则代码可以使用辅助锁[枚举器每次实际获取元素时都必须获取并释放该锁],将集合的其余部分枚举到列表中,告诉枚举器从中获取剩余数据列表,然后窃取主锁。但是,这会增加很多复杂性,如果枚举器的用户遵守适当的纪律,则不需要这样做。
    • 明白。那么这是否意味着让 IEnumerator 继承自 IEnumerator 会破坏 Liskov 替换原则?当他们在接口中指定他们接受所有 IEnumerator 时,您不能只传递一个 IEnumerator,因为这样的接口不会处理 IEnumerator,这可能会导致锁定问题,正如您所描述的.
    • @TamaMcGlinn:问题根本上是IEnumerable.GetEnumerator 可能会返回以下三件事中的任何一个:“可以安全放弃但不实现IDisposable 的对象”、“可以放弃的对象仅调用Dispose”或“无论是否调用 Dispose 都可以安全放弃的对象,并且客户端代码没有很好的方法来处理这三个。IEnumerable<T> 保证它不会返回第一种类型的对象。 IEnumerable 的原始设计者可能已经预料到它永远不会返回第二种类型的对象,但这绝不是现实的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多