例如,如果我有这样的方法:
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是固定大小的“。
这是因为可枚举的空是一个IList,所以.ToList()没有运行,然后我试图添加到一个固定的Enumberable.Empty中。我是否错误地认为这是糟糕的设计,继承IList的对象(其中定义了Add )应该支持Add?
我是被迫做var randomList = random.ToList()还是停止使用Enumberable.Empty?有什么更好的办法吗?
更新:我想我在我的例子中不清楚。我希望吞下(或记录)错误,但允许操作继续进行而不会崩溃。我的评论“我这样做是为了表明我们有一个错误”是为了告诉其他阅读代码的开发人员,这是一种不正常的行为。
提姆所提到的问题的回答就是我得到的答案。似乎我们没有常量集合的接口,所以使用了IList。
发布于 2015-10-27 09:24:24
实际上,Enumerable.Empty 返回空数组。,这就是为什么您在Array.IList.Add获得NotSupportedException的原因。数组有固定的大小。
如果您想要“发出错误信号”,我将返回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作为size提供,它还返回一个空序列。您不能再区分错误和空序列了。
当然,您也可以返回new List<int>而不是Enumerable.Empty<int>。
发布于 2015-10-27 09:27:41
更好的方法是返回null或抛出异常。返回一个空列表可以被认为是一种有效的选择,但在您的方法的上下文中则不然(例如。过滤另一个没有有效项的列表)。
失败的随机数生成似乎表明了生成算法的问题,应该抛出一个异常,而不是一个空列表。
当检索方法不能生成返回值时,应该返回'null‘还是抛出异常?
如果您总是期望找到一个值,那么如果它丢失了,那么抛出异常。这一例外将意味着存在一个问题。 如果值可能丢失或存在,并且两者对应用程序逻辑都有效,则返回一个null。
发布于 2015-10-27 09:40:14
解决此问题的另一种可能方法是使用yield break返回一个空枚举数。
IEnumerable<int> GetRandomNumbers()
{
if (generationFails)
yield break;
foreach (var element in numbers)
{
yield return element;
}
}这将使IEnumerable<int>懒洋洋地返回每个随机数。
注意,这不会导致调用代码出现错误。如果generationFails在代码执行中出现了一个错误,那么您肯定会抛出一个异常,就像其他人所说的那样。
https://stackoverflow.com/questions/33363961
复制相似问题