为什么 IEnumerable向集合添加元素后变空?
我有一个
IEnumerable
,当我迭代它并将其元素添加到列表中时,它会变成空吗?我对它的期望通常有什么问题吗 ?代码?
苹果公共类 { 私人ICollection<水果> _fruits = new List
(); public void AddFruits(IEnumerable fruits) { if (fruits == null) throw new ArgumentNullException("fruits"); foreach(水果中的水果) { _fruits.Add(水果); } } } 调用者代码:
public void AddFruits(IEnumerable
fruitsToAdd) { foreach(苹果中的苹果) { // 这里fruitsToAdd 有元素,fruitsToAdd.ToList() 有两个水果。 苹果.AddFruits(fruitsToAdd); // 这里的fruitsToAdd 没有元素!!,fruitsToAdd.ToList() 是空的! // 下一次迭代不会向下一个苹果添加任何水果,因为fruitsToAdd 为空。 } }
更新
ToList() 解决了问题。问题的根源在于 AddFruits(IEnumerablefruitsToAdd) 的调用者发送了类似的fruitsToAdd。
FruitsToAdd = obj.Fruits.Except(apples.Fruits);
每次 IEnumerablefruitsToAdd 为 Rest 时,它都会在上面的语句上运行。在下一次迭代中运行 except ,因此没有返回任何结果。
正确的方法是fruitsToAdd = obj.Fruits.Except(apples.Fruits).ToList();因为我们想要一个评估。
I have an
IEnumerable<T>
when I iterate through it and add it's element to a list it becomes empty?Is there generally anything wrong about what I expect from the code?
public class Apple { private ICollection<Fruit> _fruits = new List<Fruit>(); public void AddFruits(IEnumerable<Fruit> fruits) { if (fruits == null) throw new ArgumentNullException("fruits"); foreach (var fruit in fruits) { _fruits.Add(fruit); } } }
The caller code:
public void AddFruits(IEnumerable<Fruit> fruitsToAdd) { foreach (var apple in apples) { // Here fruitsToAdd has elements, fruitsToAdd.ToList() has two fruits. apple.AddFruits(fruitsToAdd); // Here fruitsToAdd has NO element!!, fruitsToAdd.ToList() is empty! // next iteration will not add any fruit to next apple since fruitsToAdd is empty. } }
Update
The ToList() solved the problem. The root of the problem was that the caller to AddFruits(IEnumerable fruitsToAdd) send fruitsToAdd that was like.
fruitsToAdd = obj.Fruits.Except(apples.Fruits);
Each time IEnumerable fruitsToAdd was Rest it run above statement. Which at next iteration run Except and thereby returned no fruits.
The right way is fruitsToAdd = obj.Fruits.Except(apples.Fruits).ToList(); Since we want one evaluation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好吧,试试这个:
如果不知道
fruitsToAdd
的来源,就不可能说更多。某些IEnumerable
无法重复使用。其他人可以。Ok, try this:
Without knowing the origin of your
fruitsToAdd
it's impossible to say more. SomeIEnumerable<>
can't be re-used. Others can.我修改了你的代码以使其编译并编写了一个测试。将其元素复制到苹果中后,您的列表不会变空。
I modified your code to get it to compile and wrote a test. Your list does not become empty after copying it's elements into the apples.
您问题中的代码不应表现出这种行为,因此我假设您尝试简化它,但从中删除了很多功能。
看起来有点可疑的是您的
_fruits
字段的类型为ICollection
。该接口通常与自定义集合实现一起使用。在实际代码中,该字段是否有可能不是使用List
实例化的,而是使用该接口的自定义实现实例化的?如果您有自定义集合实现,那么它的
Add
方法完全有可能执行奇怪的操作(例如在将项目添加到新的“父”集合之前从其先前的“父”集合中删除项目) 。树集合经常做这样的事情来简化移动节点。[编辑]
我知道这不是OP的实际问题,但我仍然会添加一个示例来演示自定义集合实现实际上可以修改输入集合其成员被添加到不同的集合中。
假设
Fruit
类如下所示:并且有一个自定义集合定义为:
然后以下程序:
将打印:
因为
apple.GetFruits()
将在之后返回 0第一次迭代。通过查看自定义集合的源代码,很难意识到
AddFruits
中的_children.Add(f)
实际上修改了以前的父集合的fruits。The code in your question shouldn't exhibit such behavior, so I am presuming you tried to simplify it, but removed a lot of functionality from it.
What looks a bit suspicious is that your
_fruits
field is of typeICollection<T>
. This interface is often used with custom collection implementations. Is it possible that, in the actual code, this field isn't instantiated with aList<T>
, but rather with a custom implementation of that interface?If you have a custom collection implementation, then it is perfectly possible for its
Add
method to do weird stuff (like removing an item from its previous "parent" collection before adding it to its new "parent"). Tree collections often do such things to simplify moving nodes around.[Edit]
I am aware that this is not OPs actual problem, but I will nevertheless add an example to demonstrate that a custom collection implementation can in fact modify the input collection when its members are added to a different collection.
Let's say the
Fruit
class looks like this:And there is a custom collection defined as:
Then the following program:
Would print:
Because
apple.GetFruits()
will return 0 after the first iteration.By looking at the custom collection's source, it is hard to realize that
_children.Add(f)
inAddFruits
in fact modifies the fruits previous parent collection.