If you've used C# anonymous delegates or lambdas for a while (or anonymous functions in JavaScript) you will have encountered this problem. You make a delegate for each item in a list, and they all seem to wind up referring to the last item on the list. FUME!
It's just an unfortunate side effect of the way foreach works. It reuses the same loop variable each time around the loop, and so that loop variable is created outside the scope of the loop, and so all the delegates you create inside the loop are actually looking at the same variable, not their own local copies.
This demonstrates the problem, and also gives a neat solution:
static class Extensions { public static void ForEach<T>(this IEnumerable<T> on, Action<T> action) { foreach (T item in on) action(item); } } class Program { static void Main(string[] args) { // A list of actions to execute later List<Action> actions = new List<Action>(); // Numbers 0 to 9 IEnumerable<int> numbers = Enumerable.Range(0, 10); // Store an action that prints each number (WRONG!) foreach (int number in numbers) actions.Add(() => Console.WriteLine(number)); // Run the actions, we actually print 10 copies of "9" foreach (Action action in actions) action(); // So try again actions.Clear(); // Store an action that prints each number (RIGHT!) numbers.ForEach(number => actions.Add(() => Console.WriteLine(number))); // Run the actions foreach (Action action in actions) action(); } }
By using ForEach (an extension method) instead of using foreach directly, we make the problem disappear, because now each time around the loop we have a unique number variable which is properly captured by the delegates we created.
Notes:
- The ForEach extension method I define above is actually already available as a method in the List<T> class, so if you're looping over a List<T>, you don't need that extension method.
- That extension method ought to be added to the System.Linq.Enumerable class, oughtn't it?
- One situation this can't help with is yield return. If you are looping through a list of items, and then you want to yield return each item, you're out of luck with this solution.
4 comments:
we provide a buy last chaos goldand 2moons gold and2moons power leveling wow power leveling 2moons gold andKnight Golda buy aoc gold or last chaos gold wow power levelinglast chaos gold oraoc gold
dessicant air dryer pediatric asthma asthma specialist
carpet cleaning dallas tx carpet cleaners dallas carpet cleaning dallas
beach vacations your beach vacations
bob hairstyle
bob haircuts bob layered pob hairstyle
bobbed classic bob Care for Curly Hair
Tips for Curly Hair curly hair 12r 22.5 best price
tires truck bus tires 12r 22.5 washington new house
new house Houston new house san Antonio new house ventura
sealy air beds portable portables air beds
antique doorknobs drying desiccant
air drying desiccantlipitor allergic reactionsApple prodam iphone praha
new houston house houston house tx stains removal dye
stains removal clothes stains removal teeth whitening
teeth whiteningbright teeth jennifer grey nose
jennifer nose jobs calebrities nose jobs Women with Big Noses
Women hairstyles Big Nose Women, hairstylesdvd player troubleshootingtroubleshooting with the dvd playercheap beach vacationsnight vision binoculars bargainsflorida headache clinic
hello thanks for this great information
viagra online
generic viagra
Post a Comment