List.Intersect results changing after a foreach

I have a problem with this piece of code, when I do my intersect method everything works fine.

When I do the count on my intersection before the foreach I have 1.

After the foreach, if do the count again after the foreach I have 0, why is this happening? It should always be 1...

var matchedRoles = roles.Intersect(user.Roles);
int before = matchedRoles.Count();

foreach (var matchedRole in matchedRoles)
{
    user.Roles.Remove(matchedRole);
}

int after = matchedRoles.Count();
if (matchedRoles.Any())
{
    accountRepository.Update(user);   
}

Answers


It happens because LINQ queries are lazy-evaluated: the result is not produced until it needs to be (which is whenever you call Count). It stands to reason that if you modify user.Roles in the meantime, the Count computed after the modification will be different.

If you want to "fix" the result, then you have to force LINQ to make a local copy of the results, e.g. like this:

// Here, ToArray() forces LINQ to immediately produce the results
var matchedRoles = roles.Intersect(user.Roles).ToArray();

This way, any further operations on matchedRoles will work on a fixed "snapshot" and produce the same results as long as you do not modify matchedRoles itself.


Intersect uses deferred execution. That means, every time you enumerate the result, the code is executed.

So, your second call to Count enumerates the matchedRoles enumerable a second time, causing a second execution of roles.Intersect(user.Roles). Because you removed the role from the user, it now returns no items.

To avoid this, enumerate the result once using ToList and work with the enumerated values from there:

var matchedRoles = roles.Intersect(user.Roles).ToList();

Need Your Help

Placing a Dictionary inside Viewbag

asp.net-mvc-3 model-view-controller

I'm trying to access a Dictionary in my View . But the following syntax :

Get mimetype from filename

ruby mime-types

MIME::Types.type_for(filename)

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.