【问题标题】:C#: IEnumerator<T> in a using statementC#:使用语句中的 IEnumerator<T>
【发布时间】:2010-10-30 15:30:35
【问题描述】:

我很想知道SingleOrFallback 方法是如何在MoreLinq 中实现的,并发现了一些我以前从未见过的东西:

    public static T SingleOrFallback<T>(this IEnumerable<T> source, Func<T> fallback)
    {
        source.ThrowIfNull("source");
        fallback.ThrowIfNull("fallback");
        using (IEnumerator<T> iterator = source.GetEnumerator())
        {
            if (!iterator.MoveNext())
            {
                return fallback();
            }
            T first = iterator.Current;
            if (iterator.MoveNext())
            {
                throw new InvalidOperationException();
            }
            return first;
        }
    }

为什么IEnumerator&lt;T&gt;using 语句中?在IEnumerable&lt;T&gt; 上使用foreach 时也应该考虑这一点吗?

附带问题:这个方法到底是做什么的?每当源序列不包含一个项目时,它是否返回后备项目?

【问题讨论】:

    标签: c# ienumerable idisposable using-statement ienumerator


    【解决方案1】:

    IEnumerator&lt;T&gt; 扩展了IDisposable,所以你应该在 using 语句中使用它。 foreach 自动执行此操作。 (非泛型 IEnumerator 扩展 IDisposable 但 C# 编译器仍会生成代码以有条件地调用 Dispose。这是 C# 1.0 和 1.2 之间的(少数)更改之一,其中 1.2 是 .NET 1.1 附带的版本,出于某种原因。)

    Here's an article 解释了为什么这在迭代器块的上下文中很重要。

    至于方法的作用:

    • 如果序列为空,则返回后备项
    • 如果序列只有一项,则返回它
    • 如果序列有多个项目,则抛出异常

    PS:很高兴看到 MoreLinq 得到了一些关注 :)

    【讨论】:

    • 呵呵,是的。由于 MaxBy 和 MinBy 方法,将其添加到我们的项目中。当添加类似的东西时,你总是必须检查是否还有其他可以使用的东西;)
    • 不确定这个 SingleOrFallback 方法有什么用处……你能解释一下你用它做什么吗?了解它现在的作用,但不了解何时使用这种方法:p
    • 当然:假设你有一个搜索应该返回一个结果,如果有的话。如果它不返回任何内容,您希望有某种默认值,但如果有多个结果(因为这表明存在错误),则死亡。基本上它是 SingleOrDefault 但具有指定的默认值作为函数,除非需要,否则不会被调用。
    • 啊哈。但是 SingleOrDefault 也包含一个谓词,对吗?所以要使用这个 SingleOrFallback,你会使用例如 Where(predicate) 然后 SingleOrFallback?
    • SingleOrDefault 有一个带有谓词的重载,是的。如果需要,我们也可以向 SingleOrFallback 添加一个 - 但否则 Where 会很好。
    【解决方案2】:

    如果不调用 Dispose,一些枚举器的行为会很糟糕;这对于非泛型代码和泛型代码一样正确(非泛型代码要求代码要么对 Dispose 调用进行鸭式类型,要么强制转换为 IDisposable,然后调用 IDisposable.Dispose)。确保 IEnumerator 对象被释放是一种习惯。我认为任何接受未知类型的 IEnumerable 的例程的正确性都是必要的。

    【讨论】:

      猜你喜欢
      • 2020-08-04
      • 2018-10-22
      • 1970-01-01
      • 2011-03-10
      • 1970-01-01
      • 2018-02-15
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多