So when I write something like this
Action action = new Action(()=>_myMessage = "hello");
Refactor Pro! Highlights this as a redundant delegate creation and allows me to to shorten it to
Action action = () => _myMessage="hello";
And this usually works great. Usually, but not always. For example, Rhino Mocks has an extension method named Do:
IMethodOptions<T> Do(Delegate action);
Here, passing in the first version works, but the second doesn't. What exactly is going on under the covers here?
The first version is effectively doing:
Action tmp = () => _myMessage = "hello";
var action = new Action(tmp);
The problem you're running into is that the compiler has to know what kind of delegate (or expression tree) the lambda expression should be converted into. That's why this:
var action = () => _myMessage="hello";
actually doesn't compile - it could be any delegate type with no parameters and either no return value or the same return type as _myMessage
(which is presumably string
). For instance, all of these are valid:
Action action = () => _myMessage="hello";
Func<string> action = () => _myMessage="hello";
MethodInvoker action = () => _myMessage="hello";
Expression<Action> = () => _myMessage="hello";
// etc
How could the C# compiler work out what type action
was meant to be, if it were declared with var
?
The simplest way to get round this when calling a method (for your Rhino Mocks example) is to cast:
methodOptions.Do((Action) (() => _myMessage = "hello"));