有没有办法可选地返回带有“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.
}
答案 0 :(得分:39)
如果您需要这样的东西(或立即抛出ArgumentException
之类的东西),您需要将迭代器分成两个方法:
public IEnumerable<string> GetItems() {
if (something) return null;
return GetItemsInternal();
}
private IEnumerable<string> GetItemsInternal() {
// the actual iterator with "yield return" goes here.
}
答案 1 :(得分:30)
您没有按预期使用可枚举(迭代集合中的对象)。如果你想让你的代码与现在的代码类似,你应该这样做:
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;
}
答案 2 :(得分:12)
这不是鼓励。当你谈论一个序列时,“null”通常应该具有与“空列表”相同的语义。
此外,如果没有额外的语法,就不可能将语言设计为以您希望的方式工作,因为如果您点击“yield return [whatever]
”然后点击“{{1 }}?“
答案 3 :(得分:6)
无法从迭代器方法中返回null IEnumerable<T>
。您可以在迭代器中返回null值,但不能返回null IEnumerable<T>
你可以做的是有一个包装方法,它返回null或调用真正的迭代器
static IEnumerable<string> GetItems() {
if (false) {
return GetItemsCore();
}
return null;
}
static IEnumerable<string> GetItemsCore() {
yield return "Andy";
yield return "Jennifer";
}
答案 4 :(得分:4)
虽然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;
}
}
用法
foreach (var item in YieldItems<string>(null, () =>
{
Console.WriteLine("Empty");
}))
{
Console.WriteLine(item);
}
答案 5 :(得分:2)
如果合适(当然,枚举类型必须可以为空),没有什么可以阻止你做yield return null;
。