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
Yield Return with Null
提问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 ArgumentException
immediately), 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 break
is 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 result
there 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);
}