可枚举.列表为空
本文关键字:列表 枚举 | 更新日期: 2023-09-27 18:19:28
例如,如果我有这个方法:
IEnumerable<int> GetRandomNumbers()
{
// {Codes that generate numbers as List<int>}
if(generationFails == true)
{
return Enumberable.Empty<int>(); // I do this to signal that we have an error
}
return numbers;
}
在调用方法中我做:
IEnumerable<int> AddNumber(int number)
{
var random = GetRandomNumbers();
var randomList = random as IList<int> ?? random.ToList(); // Run ToList only if needed
randomList.Add(number);
return randomList;
}
当生成失败时,我会得到一个异常"[NotSupportedException:Collection是固定大小的。]"。
这是因为Enumerable empty是一个IList,所以.ToList()没有运行,然后我试图添加到一个固定的Enumerberable.empty。我认为这是一个糟糕的设计,继承IList的对象(定义了add)应该支持add,这是错的吗?
我是被迫执行var randomList = random.ToList()
还是停止使用Enumberable.Empty
?有更好的方法吗?
更新:我想我的例子不太清楚。我希望吞下(或记录)错误,但允许操作继续而不崩溃。我的评论"我这样做是为了表明我们有错误"是为了告诉其他阅读代码的开发人员这是一种异常行为。
Tim链接的问题的答案是我想要的。似乎我们没有一个用于常量集合的接口,所以使用了IList
。
更好的方法是返回null
或抛出异常。返回一个空列表可能被认为是一个有效的替代方案,但在您的方法的上下文中不是这样(例如,过滤另一个没有有效项的列表)。
随机数生成失败似乎表明生成算法有问题,应该抛出异常,而不是空列表。
如果检索方法返回';null';或者在可能的情况下抛出异常';t产生返回值?
如果您总是期望找到一个值,那么如果该值丢失,则抛出异常。例外情况意味着存在问题。
如果该值可能丢失或存在,并且两者对应用程序逻辑都有效,则返回null。
实际上Enumerable.Empty
返回一个空数组,这就是为什么在Array.IList.Add
中得到NotSupportedException
的原因。数组具有固定的大小。
为什么数组实现IList?
如果你想"发出有错误的信号",我会返回null
而不是空序列。业务逻辑的类型检查在可读性方面是不好的。
if(generationFails == true)
{
return null; // I do this to signal that we have an error
}
然后很容易:
IEnumerable<int> random = GetRandomNumbers();
IList<int> randomList = random == null ? new List<int>() : random.ToList();
一个空的序列表明一切都很好。考虑一下,您将来将更改该方法以获取整数size
。现在有人提供0
作为大小,它也返回一个空序列。您再也无法区分错误和空序列了。
当然,您也可以返回new List<int>
而不是Enumerable.Empty<int>
。
解决此问题的另一种可能方法是使用yield break
:返回一个空枚举器
IEnumerable<int> GetRandomNumbers()
{
if (generationFails)
yield break;
foreach (var element in numbers)
{
yield return element;
}
}
这将使您的IEnumerable<int>
延迟返回每个随机数。
请注意,这不会在调用代码中单独出现错误。如果generationFails
应该在代码执行中单独列出一个错误,那么您肯定应该抛出一个异常,正如其他人所说的那样。
使用Enumerable.Empty()方法可以使用缓存的数组,而不是创建新的数组。它可以对性能产生积极影响,因为您的代码不会经常困扰垃圾回收器。
看看Enumerable.Empty()与新的"IEnumerable"()——有什么更好的?