我有一个服务(第三方),有很多签名方法,如:
int MethodA(int, string, out T result)
int MethodB(int, string, string, out T[] result)
int MethodC(DateTime, string, string, out T result)
返回int
只是一个响应代码,我实际上需要 T 。
每次调用后我都有一个错误记录逻辑(基本上调用错误处理方法,响应代码作为参数)。
我想要类似的东西:
private T GenericDataExtractor<T>(Func function) {
T result;
int responseCode = function(out result);
if(responseCode != 0)
/* handling here */
return result;
}
但是没有办法将输出参数作为参数传递给func。
更新
正如我在服务示例中提到的,使用泛型参数传递委托对我来说很重要。换句话说,我想要一个方法,它接受具有不同数量的参数的函数,但具有固定的返回类型和通用输出参数。
最后
好吧,我最终得到了这个解决方案:
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);
}
猜猜它不是最优的,所以如何改进这一点的任何建议都将受到高度评价。
答案 0 :(得分:1)
Func不支持out
参数,但自定义委托没有问题
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;
}