开发者

using Linq to generate a collection of things to be removed from another collection

I'm familiar with the problem of modifying a collection while looping over it with a foreach loop (i.e. "System.InvalidOperationException: Collection was modified"). However, it doesn't make sense to me that when I use Linq to create a List of keys to delete from a dictionary, then loop over my new List, I get the same exception.

Code before, that threw an exception:

IEnumerable<Guid> keysToDelete = _outConnections.Where(
    pair => pair.Value < timeoutPoint
).Select(pair => pair.Key);

foreach (Guid key in keysToDelete)
{
    ...some stuff not dealing with keysToDelete...
    _outConnections.Remove(key);
}

Code after, that worked:

List<Guid> keysToDelete = _outConnections.Where(
    pair => pair.Value < timeoutPoint
).Select(pair => pair.Key).ToList();

for (int i=keysToDelete.Count-1; i>=0; i--)
{
    Guid key = keysToDelete[i];
    ...some stuff not dealing with keysToDelete...
    _outConnections.Remove(key);
}

Why is this? I have the feeling that maybe my Linq queries aren't really returning a new collection, but rather some subset of the original collection, hence it accuses me of modifying the collection keysToDelete when I remove an element from _outConnections.

Update: the following fix also works, thanks to Adam Robinson:

List<Guid> keysToDelete = _outConnections.Where(
    pair => pair.Value < tim开发者_Python百科eoutPoint
).Select(pair => pair.Key).ToList();

foreach (Guid key in keysToDelete)
{
    ...some stuff not dealing with keysToDelete...
    _outConnections.Remove(key);
}


You're correct. LINQ uses what's called "deferred execution". Declaring your LINQ query doesn't actually do anything other than construct a query expression. It isn't until you actually enumerate over the list that the query is evaluated, and it uses the original list as the source.

However, calling ToList() should create a brand new list that has no relation to the original. Check the call stack of your exception to ensure that it is actually being thrown by keysToDelete.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜