如何将服务引用委托传递给具有错误处理功能的泛型方法

本文关键字:有错误 处理 功能 泛型方法 服务 引用 | 更新日期: 2023-09-27 18:18:54

我不知道如何最好地描述我想要什么,所以我将从高层次开始,然后再讨论我对实现的想法。

使用c#,我正在尝试创建一个具有泛型返回类型的方法,并将服务引用中的方法作为参数。

这个泛型方法将新建服务引用,调用我传入的服务引用的方法,执行服务引用所需的所有错误处理和检查,然后关闭或中止它并返回调用的结果。

下面的伪代码:

public T CallServiceReference<T>(method serviceRefMethod) {
  T result = null;
  ServiceReference svcClient = new ServiceReference.Client();
    try {
      result = svcClient.serviceRefMethod;
      svcClient.Close();   
    } catch (ExceptionType ex) {
      // log error message
      svcClient.Abort();
      throw;
    }
  return result;
}

这在c#中可能吗?我在找泛型和委托。我的主要问题之一是在没有实例化服务引用的情况下创建服务引用方法的委托。如果我必须实例化服务ref,我认为我最好为每个方法调用放置所有的Close, Abort和错误处理。

我正在研究不同的设计模式,尽管这有点困难,因为我不知道我正在寻找的那个的名字,或者它是否存在。

如果我能提供任何额外的信息或澄清,请告诉我。

更新(第二部分):现在我正在尝试创建一个委托,它将变量封装为它所调用的方法。

public delegate T Del<T>();
public static IEnumerable<String> GetDataFromService(String username) {
    ServiceReference.ServiceClient client = new ServiceReference.ServiceClient();
    // the method I'm going to call returns a string array
    Del<String[]> safeClientCall = new Del<String[]>(client.DataCall);
    // the above call is what I need to use so the C# compiles, but I want to do this
    // the below code throws an error...
    Del<String[]> safeClientCall = new Del<String[]>(client.DataCall(username));
    var result = DataCallHandlerMethod(ref client, safeClientCall);
    return result;
}

基本上是从我的调用方法传递username参数,并且username参数已经定义。我不想在调用委托时定义它。有什么方法可以用c#做到这一点吗?

如何将服务引用委托传递给具有错误处理功能的泛型方法

一般来说,你的答案中的一切都是可能的,除了这一行:

result = svcClient.serviceRefMethod;

这显然是一个至关重要的电话…为了动态地调用对象上的函数,您可以做几件事。一个简单的方法是将函数签名更改为:

public T CallServiceReference<T>(ServiceReference svcClient, method serviceRefMethod)

,但随后调用代码需要新建ServiceReference,并传递对svcClient.[desiredFunction]的引用作为serviceRefMethod

另一种选择是将签名更改为:

public T CallServiceReference<T>(string serviceRefMethodName)

,然后使用Reflection找到该方法并调用它。您将不会获得编译时验证(因此,如果您有错别字,它将在运行时崩溃),但您将获得动态调用。例如:

svcClient.GetType().InvokeMember(
   methodName, /* what you want to call */
   /* 
      Specifies what kinds of actions you are going to do and where / how 
      to look for the member that you are going to invoke 
    */
   System.Reflection.BindingFlags.Public | 
     System.Reflection.BindingFlags.NonPublic |
     System.Reflection.BindingFlags.Instance | 
     System.Reflection.BindingFlags.InvokeMethod, 
   null,      /* Binder that is used for binding */
   svcClient, /* the object to call the method on */
   null       /* argument list */
 );

基于你的更新的额外信息(注:这可能是一个单独的问题)

现在不仅要传入一个方法,还要传入该方法的调用。由于不是每个方法都以相同的方式调用,因此您尝试在调用站点执行此操作,但这是在实际想要调用该方法之前。从本质上讲,您要做的是在稍后才会执行的代码之间来回切换(在GetDataFromService的上下文中)。

您可以选择反射路由(在这种情况下,您传递给InvokeMember调用的参数的object[],或者您查看Func,这允许您创建一些代码,以便在调用Func时运行。例如:

 GetDataFromService(new Func<object>(() => { return client.DataCall(username); }));