Accessing local variables of the class in anonymous Action delegate

I am struggling to understand how to access local class variable in an action delegate when both the delegate is anonymous and the containing class is created just in time as an argument to a function.

The delegate seems to have access to calling functions variables, and it's containing class, but not to the class that actually contains the delegate. Please excuse me if I am not clear with my question, I am trying my best to articulate. Please refer to the code below:

public class QueryPropertyMessage
{
    public Action Callback { get; private set; }
    public string PropertyName { get; set; }
    public object PropertyValue { get; set; }

    public QueryPropertyMessage(Action callback)
    {
        this.Callback = callback;
    }

}

Class TestClass
{
    public void OuterTestFunction()
    {
        //the function will set PeropertyValue
        SomeClass.FunctionAcceptingQueryPropertyMessageObject (new QueryPropertyMessage (() =>
        {
            Helper.DebugHelper.TraceMessage ("Test Anonymous method");
            //Error The name 'PropertyValue' does not exist in the current context
            If(PropertyValue!=null)
                var val = Convert.ChangeType (PeropertyValue, typeof (bool));
        }) { PropertyName = "SomeBooleanProperty" });
    }
}

How do I access the QueryPropertyMessage object's properties inside the anonymous delegate? Reading Raymond Chen's article on anonymous methods, I seem to think that the delegate will be wrapped in another helper class, and hence what looks as containing class (QueryPropertyMessage) is not the local class from the delegates point of view. I would love to understand it little more clearly.

Jon Skeet
people
quotationmark

It's somewhat painful to do so. You basically need to declare a local variable, give it a temporary value (so that it's definitely assigned) and then use that local variable:

QueryPropertyMessage message = null;
message = new QueryPropertyMessage(() =>
{
    // Use message in here
});
SomeClass.FunctionAcceptingQueryPropertyMessageObject(message);

This is relying on the callback not being called in the constructor - otherwise it will see the original null value of message.

(Alternatively, you could change the callback to receive the message, of course.)

people

See more on this question at Stackoverflow