简体   繁体   English

Enumerable.Empty 列出

[英]Enumerable.Empty to List

If I for example have this method:例如,如果我有这个方法:

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;
}

In the calling method I do:在调用方法中,我这样做:

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;
}

and when generation fails I get an exception "[NotSupportedException: Collection was of a fixed size.]".当生成失败时,我收到一个异常“[NotSupportedException: Collection was of a fixed size.]”。

This is due to the fact that the Enumerable empty is an IList so the .ToList() is not run and I am then trying to add to a fixed Enumberable.Empty.这是因为 Enumerable empty 是一个 IList,所以 .ToList() 没有运行,然后我试图添加到一个固定的 Enumberable.Empty。 Am I wrong in thinking that this is bad design, an object that inherits IList (where Add is defined) should support Add?我认为这是一个糟糕的设计,一个继承 IList(定义 Add 的地方)的对象应该支持 Add 是否错误?

Am I forced to do var randomList = random.ToList() or stop using Enumberable.Empty ?我是被迫做var randomList = random.ToList()还是停止使用Enumberable.Empty Is there some better way?有什么更好的方法吗?

Update: I think I was unclear in my example.更新:我想我在我的例子中不清楚。 I wish to swallow (or log) the error but allow operation to continue without crashing.我希望吞下(或记录)错误,但允许操作继续而不会崩溃。 My comment "I do this to signal that we have an error" was meant to tell other developers reading the code that this is an abnormal behavior.我的评论“我这样做是为了表明我们有错误”是为了告诉其他阅读代码的开发人员这是一种异常行为。

The answer to the question Tim linked was what I was getting at.蒂姆链接的问题的答案就是我所得到的。 Seems that we just don't have an interface for constant collections so IList is used.似乎我们只是没有常量集合的接口,所以使用了IList

The better way would be returning null or throwing an exception.更好的方法是返回null或抛出异常。 Returning an empty list could considered a valid alternative, but not in the context of your method (eg. filtering another list with no valid item).返回一个空列表可以被认为是一个有效的替代方案,但不是在您的方法的上下文中(例如,过滤另一个没有有效项目的列表)。

A failed generation of random numbers seems to indicate a problem of the generation algorithm and should throw an exception, not an empty list.随机数生成失败似乎表明生成算法存在问题,应该抛出异常,而不是空列表。

Should a retrieval method return 'null' or throw an exception when it can't produce the return value? 当检索方法无法产生返回值时,它应该返回“null”还是抛出异常?

If you are always expecting to find a value then throw the exception if it is missing.如果您总是希望找到一个值,则在它丢失时抛出异常。 The exception would mean that there was a problem.异常将意味着存在问题。

If the value can be missing or present and both are valid for the application logic then return a null.如果该值可能缺失或存在,并且两者都对应用程序逻辑有效,则返回空值。

Actually Enumerable.Empty returns an empty array , that's why you get the NotSupportedException in Array.IList.Add .实际上Enumerable.Empty 返回一个空数组,这就是你在Array.IList.Add得到NotSupportedExceptionArray.IList.Add Arrays have a fixed size.数组具有固定大小。

Why array implements IList? 为什么数组实现 IList?

I would return null instead of an empty sequence if you want to "signal that there was an error".如果您想“表示存在错误”,我将返回null而不是空序列。 A type check for your business logic is not good in terms of readability.就可读性而言,对您的业务逻辑进行类型检查并不好。

if(generationFails == true)
{
    return null; // I do this to signal that we have an error
}

Then it's easy:然后很简单:

IEnumerable<int> random = GetRandomNumbers();
IList<int> randomList = random == null ? new List<int>() : random.ToList();

An empty sequence suggests that everything was fine.一个空的序列表明一切都很好。 Consider that you'll change the method in future to take an integer size .考虑到您将来会更改方法以采用整数size Now someone provides 0 as size which returns also an empty sequence.现在有人提供0作为大小,它也返回一个空序列。 You can't differentiate between an error and an empty sequence anymore.您无法再区分错误和空序列。

Of course you could also return new List<int> instead of Enumerable.Empty<int> .当然,您也可以返回new List<int>而不是Enumerable.Empty<int>

Another possible way to tackle this would be to return an empty enumerator using yield break :解决这个问题的另一种可能方法是使用yield break返回一个空的枚举器:

IEnumerable<int> GetRandomNumbers()
{
    if (generationFails)
        yield break;

    foreach (var element in numbers)
    {
        yield return element;
    }
}

This will make your IEnumerable<int> lazily return each of the random numbers.这将使您的IEnumerable<int>懒惰地返回每个随机数。

Note this will not single an error to the calling code.请注意,这不会给调用代码带来错误 If generationFails should single an error in code execution, you should definitely throw an exception, as others have stated.如果generationFails应该在代码执行中发现一个错误,那么你绝对应该抛出一个异常,正如其他人所说的那样。

With Enumerable.Empty() method you use cached array instead of creating a new one.使用 Enumerable.Empty() 方法,您可以使用缓存数组而不是创建一个新数组。 It can be positively affect performance because your code will less often bother Garbage Collector.它可以对性能产生积极影响,因为您的代码不会经常打扰垃圾收集器。

Have a look to Enumerable.Empty() vs new 'IEnumerable'() – what's better?看看Enumerable.Empty() 与新的 'IEnumerable'() - 哪个更好?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 哪个更好,Enumerable.Empty <T> 还是新的[0]? - Which is better, Enumerable.Empty<T> or new[0]? 使用Enumerable.Empty的意外行为 <string> () - Unexpected behavior using Enumerable.Empty<string>() Enumerable.Empty<t> () 等效于 IQueryable</t> - Enumerable.Empty<T>() equivalent for IQueryable Enumerable.Empty 需要显式转换<T> - Explicit cast required for Enumerable.Empty<T> 使用 Enumerable.Empty 是否更好<T> () 而不是 new List<T> () 初始化一个 IEnumerable<T> ? - Is it better to use Enumerable.Empty<T>() as opposed to new List<T>() to initialize an IEnumerable<T>? 为什么Enumerable.Empty()返回一个空数组? - Why does Enumerable.Empty() return an empty array? Null合并运算符IList,Array,Enumerable.Empty in foreach - Null coalescing operator IList, Array, Enumerable.Empty in foreach 返回 Enumerable.Empty<t> ().AsQueryable() 一个坏主意?</t> - Returning Enumerable.Empty<T>().AsQueryable() a bad idea? 将 Enumerable.Empty&lt;&gt;() 转换为另一个实现 IEnumerable 的 class 会返回 null - Casting an Enumerable.Empty<>() into another class that implements IEnumerable returns null Enumerable.Empty<t> ().AsQueryable(); 此方法支持 LINQ 到实体基础设施,不打算直接从您的代码中使用</t> - Enumerable.Empty<T>().AsQueryable(); This method supports the LINQ to Entities infrastructure and is not intended to be used directly from your code
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM