Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 299
theSpyCry Avatar asked Dec 07 '25 15:12

theSpyCry


1 Answers

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.)

like image 130
Jon Skeet Avatar answered Dec 10 '25 05:12

Jon Skeet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!