C# 收益率为空

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1765400/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 20:37:52  来源:igfitidea点击:

Yield Return with Null

c#

提问by andleer

Is there any way to optionally return a null with a "return yield" driven iterator?

有什么方法可以选择使用“返回收益”驱动的迭代器返回空值?

I would like to return a null in some cases and I don't think this is particular to IEnumerable of type string. Same goes for IEnumerable of type int etc. Thanks

在某些情况下,我想返回一个空值,我认为这不是字符串类型的 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.
}

采纳答案by Mehrdad Afshari

If you need to things like that (or throw things like ArgumentExceptionimmediately), you need to separate your iterator into two methods:

如果您需要这样的事情(或ArgumentException立即抛出类似的东西),您需要将迭代器分成两个方法:

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

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

回答by scottm

You're not using an enumerable as it was intended (to iterate objects in a collection). If you want to keep your code similar to what it is now, you should do something like this:

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

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;
}

回答by JaredPar

There is no way to return a null IEnumerable<T>from within an iterator method. You can return null values in the iterator but not a null IEnumerable<T>

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

What you could do though is have a wrapper method which either returns null or calls to the real iterator

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

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

static IEnumerable<string> GetItemsCore() {
    yield return "Andy";
    yield return "Jennifer";
}

回答by mqp

This just isn't encouraged. When you're talking about a sequence, "null" should generally have the same semantics as "empty list."

这只是不被鼓励。当您谈论序列时,“null”通常应与“空列表”具有相同的语义。

Also, it's impossible to design the language to work in the way you'd like it to work here without extra syntax, since what if you were to hit a "yield return [whatever]" and then a "return null?"

此外,如果没有额外的语法,将语言设计成您希望它在此处工作的方式是不可能的,因为如果您先点击“ yield return [whatever]”然后再点击“ return null?”怎么办?

回答by Thomas Weller

There is nothing that prevents you from doing a yield return null;, if it is appropriate (of course, the enumerated type must be nullable).

没有什么可以阻止您执行 a yield return null;,如果合适的话(当然,枚举类型必须可以为空)。

回答by Jürgen Steinblock

While yield breakis propably the best answer and it really does not matter since you always can do Items.Count()to check if greater zero or even do for each on your empty resultthere could be situations where it does matter if your result is an empty list or nothing at all and you still want to utilize the power of yield.

虽然可能yield break是最好的答案,但这真的无关紧要,因为您总是可以Items.Count()检查是否大于零,甚至在某些for each on your empty result情况下,如果您的结果是空列表或根本没有,并且您仍然想利用屈服的力量。

In that case this will help.

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

    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;
        }
    }

Usage

用法

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