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

本文关键字:函数 包装 相似 不完全 | 更新日期: 2023-09-27 18:28:33

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

TypeAService, TypeARequest, TypeAResponse
TypeBService, TypeBRequest, TypeBResponse

等等。

呼叫的模式总是一样的,类似于:

myTypeXResponse = myTypeXService.SubmitRequest(myTypeXRequest);

我需要用一些基本代码来包装这一行,这些代码通过后退和重试以及其他一些细节来处理特定的TypeXServiceException,大约有10-20行代码,我必须一遍又一遍地键入。我正在寻找一些优雅的方法来将这行代码包装在一个函数中,我可以通过指定应该调用的方法和预期的异常类型来调用该函数,比如:

myTypeXResponse = myWrapperFunction(myTypeXService.SubmitRequest, myTypeXRequest, typeof(TypeXServiceException));

我试着让函数获取并返回Object,但为了传递函数,我需要具体说明函数的签名,而我在这里无法做到这一点。我觉得Generics有办法做到这一点,但我在网上的研究并没有完全回答我的问题。

非常感谢您的帮助。

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

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

public static T myWrapperFunction<T>(Func<T, T> func, T request)
    //where T : //some common base type, if it helps
{
    return func(request);
}

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);
}

现在,我可以通过将调用封装在Action:中来获得响应对象

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

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