Reputation: 907
I have a function:
public void Execute(Expression<Action> expression)
{
var time = expression.Compile().Benchmark();
var msg = string.Format("{0} took {1} to complete",
ReflectionHelper.GetComponentCallDetails().ToString(),
time.ToString(@"hh\:mm\:ss\.ff"));
Logger.Info(msg);
}
The delegate that needs to be called is something like:
channels = GetAllChannelsImpl(maxResults);
I am relatively new to Expression Trees and cannot figure out a way to pass the Action delegate to the method.
I was able to do the same functionality using
public void Execute(Action action)
{
var time = action.Benchmark();
var msg = string.Format("{0} took {1} to complete",
ReflectionHelper.GetComponentCallDetails().ToString(),
time.ToString(@"hh\:mm\:ss\.ff"));
Logger.Info(msg);
}
and calling as
Execute(() =>
{
channels = GetAllChannelsImpl(maxResults);
});
But I wanted to use the Expression Tree based approach in order to eliminate the need to use the overhead of reflection to figure out the details of the method invoked to log it.
Can anyone suggest the right way to pass the expression tree for the above action delegate as a method parameter.
Upvotes: 1
Views: 720
Reputation: 134841
A lambda expression by itself does not have a type. The actual type it takes is inferred by the compiler depending on what you are trying to assign or cast to. With that said, any calls to your Execute()
method using simple lambdas will be ambiguous since your lambda would be compatible as an Action
or Expression<Action>
. You would have to disambiguate this by explicitly casting to the type you expect.
// assign to a variable
Expression<Action> action1 = () => ...;
Execute(action1);
// cast
Execute((Expression<Action>)(() => ...));
// use the constructor
Execute(new Expression<Action>(() => ...));
It would be better IMHO to remove the ambiguous overload and rename one of the methods. I'd recommend renaming the expression overload to ExecuteExpression()
.
Upvotes: 2