I would like to have a "generic" - that is, a method with a single signature if possible - instead of this rather copy/paste code below.
My goal is to "wrap" methods from a third party DLL with a Spy Double
int spy(Func<int> method)
{
methodCalls.Add(method.Method.Name);
return method.Invoke();
}
int spy(Func<string, int> method, string arg)
{
methodCalls.Add(method.Method.Name);
return method.Invoke(arg);
}
private int spy(Func<int, int> method, int arg)
{
methodCalls.Add(method.Method.Name);
return method.Invoke(arg);
}
You see the problem: I have almost identical method blocks... Is there a way to avoid this and still accomplish the desired behavior?
Well you could start off by making them generic:
public TResult Spy<TResult>(Func<TResult> method)
{
methodCalls.Add(method.Method.Name);
return method();
}
public TResult Spy<TArg, TResult>(Func<TArg, TResult> method, TArg arg)
{
methodCalls.Add(method.Method.Name);
return method(arg);
}
public TResult Spy<TArg1, TArg2, TResult>
(Func<TArg1, TArg2, TResult> method, TArg1 arg1, TArg2 arg2)
{
methodCalls.Add(method.Method.Name);
return method(arg1, arg2);
}
...
That at least means you only need as many overloads as the maximum number of parameters you want to handle. You won't easily be able to do better than that without losing compile-time type-safety.
See more on this question at Stackoverflow