I have a service (3-rd party) with a lot of methods with signatures like:
int MethodA(int, string, out T result)
int MethodB(int, string, string, out T[] result)
int MethodC(DateTime, string, string, out T result)
Where returning int
is just a response code, and I actually need T's.
After each call I have an error logging logic (basically calling error handling method with response code as argument).
I wanted something like:
private T GenericDataExtractor<T>(Func function) {
T result;
int responseCode = function(out result);
if(responseCode != 0)
/* handling here */
return result;
}
But there is no way to pass output parameter as argument to func.
UPDATE
As I mentioned in service example, it's important for me to pass delegate with generic arguments. In other words I want a method, that accepts a functions with different number of arguments, but with fixed return type and generic out parameter.
IN THE END
Well, I ended up with this solution:
protected delegate int KeeperAPIDelegate<TReturn>(string sessionID, out TReturn rObj);
protected delegate int KeeperAPIDelegate<T1, TReturn>(string sessionID, T1 obj1, out TReturn rObj);
protected delegate int KeeperAPIDelegate<T1, T2, TReturn>(string sessionID, T1 obj1, T2 obj2, out TReturn rObj);
protected delegate int KeeperAPIDelegate<T1, T2, T3, TReturn>(string sessionID, T1 obj1, T2 obj2, T3 obj3, out TReturn rObj);
protected TReturn DataGrabber<TReturn>(KeeperAPIDelegate<TReturn> action)
{
TReturn data;
int result = action.Invoke(SessionID, out data);
if (result == 0) return data;
throw HandleError(result);
}
protected TReturn DataGrabber<T1, TReturn>(KeeperAPIDelegate<T1, TReturn> action, params object[] args)
{
TReturn data;
int result = action.Invoke(SessionID, (T1)args[0], out data);
if (result == 0) return data;
throw HandleError(result);
}
protected TReturn DataGrabber<T1, T2, TReturn>(KeeperAPIDelegate<T1, T2, TReturn> action, params object[] args)
{
TReturn data;
int result = action.Invoke(SessionID, (T1)args[0], (T2)args[1], out data);
if (result == 0) return data;
throw HandleError(result);
}
protected TReturn DataGrabber<T1, T2, T3, TReturn>(KeeperAPIDelegate<T1, T2, T3, TReturn> action, params object[] args)
{
TReturn data;
int result = action.Invoke(SessionID, (T1)args[0], (T2)args[1], (T3)args[2], out data);
if (result == 0) return data;
throw HandleError(result);
}
Guess it's not optimal, so any suggestions how to improve this will be highly appritiated.