-1

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.

Kindzoku
  • 1,368
  • 1
  • 10
  • 29

1 Answers1

1

Func doesn't not support out parameters, but there is no problem with custom delegate

public delegate int MyFunction<T>(out T parameter);

private T GenericDataExtractor<T>(MyFunction<T> function, out T result){
    T result;
    int responseCode = function(out result);
    if(responseCode != null) /* handling here */
    //the if above is always true :)
    return result;
}
pwas
  • 3,225
  • 18
  • 40