C# 具有相似但不完全相同签名的函数的包装器

C# 具有相似但不完全相同签名的函数的包装器,c#,function,generics,wrapper,C#,Function,Generics,Wrapper,我使用的是第三方API,它有许多不同但相似的HTTP相关对象,例如: TypeAService, TypeARequest, TypeAResponse TypeBService, TypeBRequest, TypeBResponse 等等 呼叫的模式总是相同的,类似于: myTypeXResponse = myTypeXService.SubmitRequest(myTypeXRequest); myTypeXResponse = myWrapperFunction(myTypeXSe

我使用的是第三方API,它有许多不同但相似的HTTP相关对象,例如:

TypeAService, TypeARequest, TypeAResponse

TypeBService, TypeBRequest, TypeBResponse
等等

呼叫的模式总是相同的,类似于:

myTypeXResponse = myTypeXService.SubmitRequest(myTypeXRequest);
myTypeXResponse = myWrapperFunction(myTypeXService.SubmitRequest, myTypeXRequest, typeof(TypeXServiceException));
我需要用一些基本代码来包装这一行,这些代码通过后退和重试来处理特定的
TypeXServiceException
,以及一些其他细节,大约10-20行代码,我必须反复键入。我正在寻找一种优雅的方法,将这行代码封装到一个函数中,通过指定应该调用的方法和预期的异常类型,我可以调用该函数,比如:

myTypeXResponse = myTypeXService.SubmitRequest(myTypeXRequest);
myTypeXResponse = myWrapperFunction(myTypeXService.SubmitRequest, myTypeXRequest, typeof(TypeXServiceException));
我试着让函数获取并返回对象,但是为了传递函数,我需要明确函数的签名,我在这里做不到。我觉得有一些方法可以用泛型来做到这一点,但我在网上的研究并没有给我任何能完全回答我问题的答案


非常感谢您的帮助。

您可以使用泛型来处理此问题:

public static T myWrapperFunction<T>(Func<T, T> func, T request)
    //where T : //some common base type, if it helps
{
    return func(request);
}
publicstatict myWrapperFunction(Func-Func,T-request)
//其中T://一些常见的基类型,如果有帮助的话
{
返回func(请求);
}

Servy针对这个问题提出的方法(在我上一篇评论中进行了修订)已经很好地工作了一段时间,但我最近用一种不同的方法解决了一个类似的问题,使用委托而不是泛型。我将在这里发布,以防其他人可以从代码中获益:

public delegate bool TryAgainAfterException(Exception ex);

public void RepeatAction(Action action, TryAgainAfterException tryAgainFunction)
{
   // set up whatever logic you would use for your do-while loop here
   bool tryAgain;

   do
   {
      tryAgain = false;
      try
      {
         action();
      }
      catch (Exception ex)
      {
         if (tryAgainFunction(ex))
         {
            // the specific logic of the Exception
            // handling would go here, including:
            tryAgain = true;
         }
         else
            throw ex;
      }
   }
   while (tryAgain);
}
现在,我可以通过将调用包装到操作中来获取响应对象:

RepeatAction( () => { myTypeXResponse = myTypeXService.SubmitRequest(myTypeXRequest); },
              e => e.GetType() == TypeXServiceException );

我不是真的提倡一种方法胜过另一种方法,但我也想分享一下这个方法。

谢谢。电话是什么样子的?您能否解释和/或让我参考一些资源,从中我可以了解有关概念的更多信息?@user2524845它与您在示例中的使用方式完全相同。你可以使用谷歌查找相关主题的信息来源;这是一个很棒的资源。当我尝试此操作时,我遇到了错误:错误7“TypeBreresponse TypeBService.SubmitRequest(TypeBRequest)”的返回类型错误,错误8无法将类型“TypeBRequest”隐式转换为“TypeBreresponse”,我将函数头更改为:public static R SubmitTypeSpecificRequest(函数submitRequestFunction,T请求)这似乎很有效。再说一次,我是泛型新手,所以我不知道我做对了什么,甚至不知道我做对了什么。如果他的答案解决了你的问题,你为什么不升级投票并把他的帖子标记为你问题的答案?@julealgon没有升级投票的责任,但是的,它应该被标记为答案。我对Ettiq不熟悉在这里,我从来没有完全掌握过互联网社交惯例的诀窍。但他的回答不完整。他说他打电话的方式正是我所需要的,但只有在我根据我的评论修改后才起作用。所以我不确定是否应该将其标记为答案。