c# - IEnumerable——非空集合如何同时为空?

标签 c# ienumerable

我想不通。传递 IEnumerable(T 是我的一些类,但这里不相关)的工作流程基本上是这样的:

var a = GetEntireCollection(); // so I get IEnumerable<T>
...
var b = a.Where(condition1);
...
var c = b.Where(condition2);
...

所以我从集合中过滤出越来越多的项目,最后我调用:

if (z.IsEmpty())
    throw new Exception();
Foo(z);

而 Foo 是

public void Foo(IEnumerable<T> p)
{
    pool = p.OrderByDescending(it => it.MyProperty).ToList();

    if (pool.IsEmpty())
        throw new Exception(pool.Count().ToString() + ", " + p.Count().ToString());
    ...

我所做的就是订购系列。

现在,我的程序因异常而崩溃——它说 p 的计数 = 1,池的计数 = 0。此外,当我指出 p 并要求结果时(我使用 Visual Studio 运行程序)它说,该集合没有产生任何结果(或类似的东西,不是逐字引用)。

问题:

  1. 非空集合如何通过重新排序变为空?
  2. 当集合中没有任何项目时,集合计数怎么会 > 0?

我问是因为我想知道如何避免这种情况,但老实说,当我查看代码时,它对我来说似乎 100% 合法。

技术背景:

  • 它是纯 C# 代码,没有 asm 内联,或类似的东西
  • 没有话题
  • 没有外部库,除了 Where(来自 Linq)这是我所有的代码

编辑

编辑 1

public static bool IsEmpty<T>(this IEnumerable<T> coll)
{
    var iter = coll.GetEnumerator();
    return !iter.MoveNext();
}

编辑2

就在调用 Foo(z) 之前,我检查 z 是否为空,因此代码如下所示:

if (z.IsEmpty())
    throw new Exception();
Foo(z);

已解决

正如 Jon 所建议的(我会说 C# sharpshooting),其中一个条件是时间相关的。因此,当强制执行集合评估时,条件发生了变化,实际上我得到了另一个集合。

最佳答案

一种可能性是,两次评估条件会有效地改变结果。

每次遍历 p 时,它都会重新评估数据,包括 Where 子句。因此,您这样做一次是为了填充 pool,然后再次打印出 p.Count()

如果没有关于 GetEntireCollection 做什么或 Where 条件是什么的更多信息,很难说发生了什么......但这是一种可能的解释。如果您可以发布一个简短但完整的程序来演示该问题,那将大有帮助。

关于c# - IEnumerable——非空集合如何同时为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3624119/

相关文章:

c# - 如何获得一系列时间 block 的所有非重叠排列?

c# - 合并大文件的最佳方法是什么?

c# - 使用 block 时的编译器错误

c# - 找出 C# 枚举器

c# - 如何在条款查询(ElasticSearch NEST C#)中添加条款?

c# - 有什么方法可以在不重载函数的情况下将 MongoDB ObjectId 用作 C# 中的可选参数

C# 锯齿状数组 : compiler cannot implicitly convert type 'char[]' to 'int[]' . 为什么?

c# - 为什么 .net 中的数组只实现 IEnumerable 而不是 IEnumerable<T>?

c# - 比较 IEnumerable<T> 的类型

.net - .Net 中的 IOrderedEnumerable.ThenBy() 如何工作?