可枚举.列表为空

本文关键字:列表 枚举 | 更新日期: 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"()——有什么更好的?