I have many methods that require some logging with the same pattern. Some methods need to return some value, some don't. I have created a method with Action parameter to avoid copypasting all of the logic. It looks like this:
private void Execute(Action action)
{
Logger.Start();
try
{
action();
}
catch(Exception exception)
{
Logger.WriteException();
throw;
}
finally
{
Logger.Finish();
}
}
Now I have some calls that like that
public void DoSomething(string parameter)
{
Execute(() => GetProvider(parameter).DoSomething());
}
But I need some function that return values. What are the best ways to do it? I have found two now:
1) Create a copy of Execute method with Func
private T Execute<T>(Func<T> action)
{
Logger.Start();
try
{
return action();
}
catch(Exception exception)
{
Logger.WriteException();
throw;
}
finally
{
Logger.Finish();
}
}
This method works but has some copy paste as well.
2) Trick the parameter into being an Action:
public Result DoSomething(string parameter)
{
Result result = null;
Execute(() => result = GetProvider(parameter).DoSomething());
return result;
}
This does not require copy paste but does not look so nice.
Is there a way to join Action and Func somehow to avoid any of these methods or may be there is another way to achieve the same result?
A third option is to still overload Execute
, but make the Action
version work in terms of the Func
version:
private void Execute(Action action)
{
// We just ignore the return value here
Execute(() => {
action();
return 0;
});
}
Of course all this would be simpler if void
were more like a "real" type (like Unit
in F# et al), at which point we could just have Task<T>
instead of Task
and Task<T>
as well...