theSpyCry
theSpyCry

Reputation: 12283

C# Anonymous method variable scope problem with IEnumerable<T>

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

Answers (1)

Jon Skeet
Jon Skeet

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

Related Questions