Reputation: 12283
I'm trying to iterate through all components and for those who implements ISupportsOpen allow to open a project. The problem is when the anonymous method is called, then the component variable is always the same element (as coming from the outer scope from IEnumerable)
foreach (ISupportsOpen component in something.Site.Container.Components.OfType<ISupportsOpen>())
{
MyClass m = new MyClass();
m.Called += new EventHandler(delegate(object sender, EventArgs e)
{
if (component.CanOpenProject(..)) component.OpenProject(..);
});
itemsList.Add(m);
}
How should it be solved, please?
Upvotes: 3
Views: 1099
Reputation: 1502386
Just don't close over the loop variable - copy it:
foreach (ISupportsOpen component in
something.Site.Container.Components.OfType<ISupportsOpen>())
{
ISupportsOpen copy = component;
MyClass m = new MyClass();
m.Called += new EventHandler(delegate(object sender, EventArgs e)
{
if (copy.CanOpenProject(..)) copy.OpenProject(..);
});
itemsList.Add(m);
}
This way you get a new "instance" of the copy
variable for each iteration of the loop - so each delegate will capture that different instance. Before, every delegate was capturing the same variable.
(This is in some ways a duplicate question, but it's the kind of problem which is relatively hard to search for, so I'm happy to answer it many times.)
Upvotes: 5