c# – 语法问题使用yield return的IEnumerable方法

前端之家收集整理的这篇文章主要介绍了c# – 语法问题使用yield return的IEnumerable方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这是我的方法
static IEnumerable<DateTime> GetMonths(DateTime from,DateTime to)
{
    // if logs is not uptodate
    TimeSpan logsMissingTimespan = to - from;

    if (logsMissingTimespan != new TimeSpan(0))
    {
        return GetMonthsBetweenTwoDates(from,to);
    }

    return null; // Why this line ?
}

private static IEnumerable<DateTime> GetMonthsBetweenTwoDates(DateTime from,DateTime to)
{

    DateTime date = from;
    DateTime lastDate = DateTime.MaxValue;

    while (date < to)
    {
        if (lastDate.Month != date.Month)
        {
            lastDate = date;
            yield return lastDate;
        }
        date = date.AddDays(1);
    }
}

它工作正常,但我想我可以写一些像这样清洁的东西:

static IEnumerable<DateTime> GetMonths(DateTime from,DateTime to)
{
    TimeSpan logsMissingTimespan = to - from;

    if (logsMissingTimespan == new TimeSpan(0))
    {
        yield break;
    }

    return GetMonthsBetweenTwoDates(from,to);
}

但是我有一条错误消息:

Cannot return a value from an iterator. Use the yield return statement to return a value,or yield break to end the iteration.

为什么我应该返回null并且语法正确?

编辑:

所以,正确的方法是使用Enumerable.Empty:

static IEnumerable<DateTime> GetMonths(DateTime from,to);
    }

    return Enumerable.Empty<DateTime>();
}

解决方法

前两个示例的形式产生不同类型的输出.

您的第一个示例返回IEnumerable< T>如果条件满足则直接,如果不满足则为空引用.您的第二个示例始终返回IEnumerable< T>,但条件确定它是否具有任何元素.

第二个例子是使用迭代器块完成的. C#编译器使用yield语法将您编写的函数转换为实现IEnumerable< T>的自定义(隐藏)类型.和实现IEnumerator< T>的类型.这些类型实现了必要的状态机,以实现(希望)您放入函数的逻辑.因此,你不能混淆范式;你必须要么返回IEnumerable< T>的实例.来自函数(并且根本不使用yield),或者必须通过yield返回所有内容.

如果你所关心的是你正在返回一个空引用的事实,你可以通过返回Enumerable.Empty< DateTime>来使方法在语义上相同.而不是null.

猜你在找的C#相关文章