收益率为零

and*_*eer 32 c#

有没有办法可选地返回一个带有"return yield"驱动迭代器的null?

我想在某些情况下返回null,我不认为这是IEnumerable类型字符串的特殊情况.同样适用于类型为int等的IEnumerable.谢谢

static void Main(string[] args)
{
    var Items = GetItems();

    if (Items != null)
    {
        foreach (var item in Items)
        {
            Console.WriteLine(item);
        }
    }
    else
    {
        Console.WriteLine("<null>");
    }
}

static IEnumerable<string> GetItems()
{
    if (false)
    {
        yield return "Andy";
        yield return "Jennifer";
    }

    return null; // <- Compiler Error:
    // Cannot return a value from an iterator. 
    // Use the yield return statement to return a value,
    // or yield break to end the iteration.
}
Run Code Online (Sandbox Code Playgroud)

Meh*_*ari 39

如果你需要这样的东西(或ArgumentException立即扔东西),你需要将你的迭代器分成两个方法:

 public IEnumerable<string> GetItems() {
     if (something) return null;
     return GetItemsInternal();
 }

 private IEnumerable<string> GetItemsInternal() {
     // the actual iterator with "yield return" goes here.
 }
Run Code Online (Sandbox Code Playgroud)


sco*_*ttm 31

您没有按预期使用可枚举(迭代集合中的对象).如果你想让你的代码保持与现在类似,你应该这样做:

static void Main(string[] args)
{
    var Items = GetItems();

    foreach (var item in Items) //this will not enter the loop because there are no items in the Items collection
    {
            Console.WriteLine(item);
    }

    //if you still need to know if there were items, check the Count() extension method
    if(Items.Count() == 0)
    {
      Console.WriteLine("0 items returned");
    }


}

static IEnumerable<string> GetItems()
{
    if (false)
    {
        yield return "Andy";
        yield return "Jennifer";
    }

    yield break;
}
Run Code Online (Sandbox Code Playgroud)


mqp*_*mqp 12

这不是鼓励.当您谈论序列时,"null"通常应具有与"空列表"相同的语义.

此外,如果你没有额外的语法,就不可能将这种语言设计成你希望它在这里工作的方式,因为如果你要点击" yield return [whatever]"然后是" return null?"

  • 我同意,这是一个意图问题.简单地通过函数而没有达到'yield return'将产生一个空序列.用于检查的Resposibilty是空的序列属于其他东西. (2认同)

Jar*_*Par 6

无法IEnumerable<T>从迭代器方法中返回null .您可以在迭代器中返回null值,但不能返回nullIEnumerable<T>

你可以做的是有一个包装器方法,它返回null或调用真正的迭代器

static IEnumerable<string> GetItems() {
    if (false) {
        return GetItemsCore();
    }
    return null;
}

static IEnumerable<string> GetItemsCore() {
    yield return "Andy";
    yield return "Jennifer";
}
Run Code Online (Sandbox Code Playgroud)


Jür*_*ock 5

虽然可能yield break是最佳答案,但实际上并不重要,因为您始终可以Items.Count()检查是否大于零,甚至在某些for each on your empty result情况下,如果结果为空列表或什么都不是很重要,并且您仍然想利用产量的力量。

在这种情况下,这将有所帮助。

    private IEnumerable<T> YieldItems<T>(IEnumerable<T> items, Action empty = null)
    {
        if (items == null)
        {
            if (empty != null) empty();
            yield break;
        }

        foreach (var item in items)
        {
            yield return item;
        }
    }
Run Code Online (Sandbox Code Playgroud)

用法

        foreach (var item in YieldItems<string>(null, () =>
        {
            Console.WriteLine("Empty");
        }))
        {
            Console.WriteLine(item);
        }
Run Code Online (Sandbox Code Playgroud)