BlendSkill
BlendSkill

Reputation: 41

Accessing elements from a lambda expression in c#?

I would like to access my WPF element from a lambda expression.

Here is my simplified code:

public static class MyClass
{
    public struct MyStruct
    {
        public Rectangle MyRectangle {get; set;}
        public Button MyButton {get; set;}

        public void MyVoid()
        {
            MyRectangle = new Rectangle();
            MyRectangle.Width = 300;
            MyRectangle.Height = 100;
            MyGrid.Children.Add(MyRectangle);

            MyButton = new Button();
            MyButton.Widht = 200;
            MyButton.Height = 200;
            MyButton.Click += (a, e) =>
            {
                MyRectangle.Fill = Brushes.Red;
            }
            MyGrid.Children.Add(MyButton);
        }
    }
}

But there is an error with MyRectangle in "MyButton.Click" :

Anonymous methods, lambda expressions, and query expressions in structs cannot access instance members of "this".

Can someone explain how to fix this error?

Upvotes: 0

Views: 204

Answers (2)

BlendSkill
BlendSkill

Reputation: 41

Your solution did not work for me. To solve the problem, I deleted the anonymous method and created another one outside of the "MyVoid" method.

Upvotes: 0

weichch
weichch

Reputation: 10035

The easy fix, as per @Sean said, change struct to class.

If it has to be struct, you need to deference this to a local variable:

MyStruct self = this;

MyButton.Click += (a, e) =>
{
    // Assuming Rectangle here is System.Windows.Shapes.Rectangle
    self.MyRectangle.Fill = Brushes.Red;
}

I can also give you some explanation about the error:

The error is because this which is effectively ref this in struct is a pointer which cannot be captured and stored in Delegate.Target.

In order to get this captured by a delegate, you will need to dereference this to a local variable and capture the value in the variable.

However, when you do the above, the compiler creates a defensive copy, meaning self is a copy of the struct where this points to. This means, whilst you can still make changes to fields / properties whose return types are reference types, any changes made to self instance itself as well as those value type returning fields / properties won't be reflected in this.

Upvotes: 1

Related Questions