Reputation: 2548
An interesting problem with IEnumerable and Linq.
static void Main(string[] args)
{
var subject = "#Accountancy #premier #Agile #Apache #automation #Automation #banking #Banking #bankIngs #AutoMation";
var hashtags = subject.Split('#').Select(hashtag => hashtag.Trim().ToUpper()).Distinct();
var plurals = hashtags.Where((hashtag) =>
{
return hashtags.Contains($"{hashtag.ToUpper()}S");
}).Select(h => $"{h.ToUpper()}S"); //.ToList(); (1) - will not break
//filter hashtags
hashtags = hashtags.Except(plurals); //.ToList(); (2) - will not break
//if iterate, would break with:
//System.StackOverflowException was unhandled Message: An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll
foreach (var hashtag in hashtags)
{
Console.WriteLine(hashtag);
}
Console.Read();
}
Curious on how would one explain why overflow exception occurs?
Upvotes: 3
Views: 305
Reputation: 27367
Walk through it step by step.
To execute 2, you must execute 1. However, hashtags is continually changing, so plurals is trying to execute not on the original collection, but on the result of 2 (which again, relies on the result of 1).
Your query will attempt to be:
hashtags = hashtags.Except(plurals);
Replacing plurals
hashtags = hashtags.Except(
hashtags.Where(hashtag => { return hashtags.Contains($"{hashtag.ToUpper()}S"); })
.Select(h => $"{h.ToUpper()}S")
);
But hashtags
is hashtags.Except(plurals);
hashtags.Except(
hashtags.Except(plurals).Where(hashtag => { return hashtags.Contains($"{hashtag.ToUpper()}S"); })
.Select(h => $"{h.ToUpper()}S")
);
And then we need to replace plurals
again.. and so on.
Your fixes (adding .ToList()
) is the logical way to fix it.
Upvotes: 4
Reputation: 405
You are re-assigning hashtags (which has not been evaluated) to another evaluation which is resulting in an infinite loop. If you put the second evaluation in another variable, it will work:
var hashtags2 = hashtags.Except(plurals);
foreach (var hashtag in hashtags2)
{
Console.WriteLine(hashtag);
}
Upvotes: 3