To make the Solution 1 more accurate:
To make the code compile, it should be included in the class definition like this:
using System;
public class Command {
public Command(Action<object> action) {
}
public Command(Action execute)
: this((Action<object>)(o => execute())) {
}
}
The constructor could not be of the type
Command(Action<>)
;
Action<>
would not be a
complete type. At the same time, the call to the other constructor clearly indicate that the actual generic parameter of the first constructor is
Action<System.Object>
.
So, let's see what's going on. I hope, first constructor (which you did not show) is clear. It does not matter what its implementation does; but the delegate instance
action
can be invoked in this constructor, or just preserved to be invoked later, eventually. This delegate instance has a parameters of the type
System.Object
, which is passed to the delegate instance passed as a parameter to the first constructor. For the declaration of all
Action
delegates, see the namespace
System
, assembly "System.Core".
The second constructor accepts the parameters of the type
System.Action
, which is the void delegate without a parameter. The whole purpose of this constructor call the constructor above (which is done in the part of the construct after ':'), and
the trick is to ignore System.Object
the parameter of the
action
, which is represented by the parameter
o
in the
delta expression. The constructor implementation wraps the method ignoring the parameter in this lambda expression.
[EDIT, in response to some follow-up questions below]
In the code sample above, the "type cast" syntax is used, the (complete) type in round brackets,
(Action<object>)
. This is done because of
type inference used in
lambda expressions. Indeed, the type of the object
o
is not specified. Even though the parameter is ignored, the implementation needs to know its type. Sometimes, one can infer the type from the fact that there is only one other constructor; this is the inference I have to perform to answer this question. But this is not how the compiler's type inference works; it needs more certain information.
See also:
Implicitly Typed Local Variables (C# Programming Guide)[
^].
I don't like the syntax shown above and usually use slightly different syntax, with a constructor:
public class Command {
public Command(Action<object> action) {}
public Command(Action execute)
: this(new Action<object>(o => execute())) {
}
}
—SA