【问题标题】:C# Iterator can not contain return statementC#迭代器不能包含return语句
【发布时间】:2016-04-24 08:28:21
【问题描述】:

我正在尝试在 c# 中实现类似 python 的范围数据结构,女巫实现 IEnumerable<int>

我的 Range 结构有 3 个整数字段:start, stop, step

我还编写了RangeIterator 数据结构,它实现了IEnumerator<int> 并接受范围对象到它的构造函数。因为我想解耦 range iterator 对象和 range 对象。

我在Range struct 中写道:

    public IEnumerator<int> GetEnumerator()
    {
        return new RangeIterator(ref this);
    }

一切正常。

但在某些情况下,由于start, stop, step 参数,该范围不应生成数字。我想检查它是否应该在创建 RangeIterator 对象之前生成数字以进行优化。

我将代码更改为:

        public IEnumerator<int> GetEnumerator()
        {
            if (!ShouldGenerate)
            {
                yield break;
            }
            return new RangeIterator(ref this);
        }

但它说

迭代器不能包含return语句

在这种情况下如何避免创建RangeIterator

对不起,英语不是我的母语。

编辑 1:

我在this answer 中找到了错误原因,但我不知道如何避免在不需要时创建枚举器对象。

【问题讨论】:

  • 谢谢,我找到了错误原因,但没有解决问题。
  • 你见过Enumerable.Range(int, int)Enumerable.Empty&lt;T&gt;()吗?您可以通过阅读参考源来了解这些是如何实现的。
  • 谢谢。我用Enumerable.Empty&lt;int&gt;().GetEnumerator()解决。
  • 出于好奇:为什么RangeIterator 构造函数的ref 参数?我只是看不出这可能有什么用途。

标签: c# data-structures struct ienumerable ienumerator


【解决方案1】:

我在这个答案中找到了错误原因,但我不知道如何避免在不需要时创建枚举器对象。

您无法避免枚举器对象,因为不允许返回 null。但是您可以通过使用静态 singleton 实例来避免不必要的枚举器对象分配(因为根据定义,空枚举器是不可变的)。例如,像这样使用从Enumerable.Empty&lt;T&gt;() 返回的那个

public IEnumerator<int> GetEnumerator()
{
    if (!ShouldGenerate)
        return Enumerable.Empty<int>().GetEnumerator();
    return new RangeIterator(ref this);
}

【讨论】:

    【解决方案2】:

    可能是这样的:

    public IEnumerator<int> GetEnumerator()
    {
       return (ShouldGenerate) ? new RangeIterator(ref this) : new RangeIterator(); // an empty iterator
    }
    

    【讨论】:

    • 我不这么认为...但是生成从零开始的大小迭代器只会影响性能:)
    猜你喜欢
    • 1970-01-01
    • 2012-12-07
    • 2022-12-05
    • 2014-06-14
    • 2011-01-25
    • 1970-01-01
    • 2020-02-22
    • 2019-06-16
    • 1970-01-01
    相关资源
    最近更新 更多