tags:

views:

115

answers:

3

I have this code:

        String temp = txtForm.Rtf;

        foreach (ReplaceStrut rs in replaceArray) {
            temp = temp.Replace(rs.getNeedle(), rs.getReplacement());
        }
        if (this.InvokeRequired) {
            this.Invoke(temp => txtForm.Rtf = temp);
        } else {
            txtForm.Rtf = temp;
        }

But it won't compile. It complains about two things, "Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type" and, "A local variable named 'temp' cannot be declared in this scope because it would give a difference meaning to 'temp', which is already used in a 'parent or current' scope to denote something else"

Both error are on the lambda line. How can I make this work, what am I doing wrong?

A: 
this.Invoke((Action) () => txtForm.Rtf = something); // where something is free
leppie
this doesn't quite work. I found out lamba's actually have access to current scope variables so passing it temp is unnecessary. Fix your answer and I'll mark it as the right one
Malfist
Good point :) Obviously some argument would have to be passed then :p
leppie
No, you have to use temp, not 'something' Something is in neither scope, therefor it'd have to be passed.
Malfist
Elisha has the correct answer
Malfist
For the cast to work, an extra set of parentheses are required around the lambda expression.
Phil Ross
+4  A: 
this.Invoke(new Action(() => txtForm.Rtf = temp))
Elisha
Never seen the syntax used like this :p Not sure if I like it or not.
leppie
The `new Action(() => ...)` syntax is identical in terms of the generated IL to `(Action)(() => ...)`.
Phil Ross
+5  A: 

The "cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type" error is occurring because lambda expressions do not have types. The compiler usually infers the type from the target of the assignment, but this is not possible with Invoke because it takes a System.Delegate. Casting the lambda expression will solve this problem.

It isn't necessary to declare temp as a parameter of your lambda expression. The expression will be able to refer to temp from the containing scope.

Change your Invoke line to the following and it should work:

this.Invoke((Action)(() => txtForm.Rtf = temp));

Make sure you are referencing the System.Core assembly for the above line, otherwise you'll get an error saying "Using the generic type 'System.Action' requires '1' type arguments".

Phil Ross
+1 for the explaination
Davy8