2013-07-04 92 views
2

我正在试图创建两个泛型方法,其中一个是void,另一个是返回类型。 void方法使用Action委托,另一个使用Func委托。对于无效的方法实现是这样的:带委托参数的泛型方法

public static void ExecuteVoid<T>(Action<T> actionToExecute) 
    { 
     string endpointUri = ServiceEndpoints.GetServiceEndpoint(typeof(T)); 

     using (ChannelFactory<T> factory = new ChannelFactory<T>(new BasicHttpBinding(), new EndpointAddress(endpointUri))) 
     { 
      T proxy = factory.CreateChannel(); 

      actionToExecute(proxy); 
     } 
    } 

这工作得很好,但我与非void方法有问题:

public static T ExecuteAndReturn<T>(Func<T> delegateToExecute) 
    { 
     string endpointUri = ServiceEndpoints.GetServiceEndpoint(typeof(T)); 

     T valueToReturn; 

     using (ChannelFactory<T> factory = new ChannelFactory<T>(new BasicHttpBinding(), new EndpointAddress(endpointUri))) 
     { 
      T proxy = factory.CreateChannel(); 

      valueToReturn = delegateToExecute(); 
     } 

     return valueToReturn; 
    } 

现在,当我尝试做一个呼叫像这样的方法:

var result = ServiceFactory.ExecuteAndReturn((IMyService x) => x.Foo()); 

我得到这个编译错误:

The type arguments for method 'ServiceFactory.ExecuteAndReturn<T>(System.Func<T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly. 

Foo()在这种情况下是一个没有参数返回object的方法。然后我试图通过明确指定类型调用的方法:

var result = ServiceFactory.ExecuteAndReturn<IMyService>(x => x.Foo()); 

,但现在我得到另一个异常说

Delegate 'IMyService' does not take 1 arguments. 

我真的失去了这里。任何帮助表示赞赏。

+0

IMyService的定义是什么? –

+0

@terrybozzio在这种情况下会是什么类型的'x'呢?该类型需要以某种方式指定。 – PoweredByOrange

回答

6

您可能会将返回类型与代理类型混淆。如果将参数指定为Func<T>,则T需要是函数的返回类型,而不是代理类型。但是,您还需要指定代理类型,以获得正确的服务端点和渠道工厂。因此,您实际上需要两个类型参数:一个用于代理,一个用于返回类型。我还假设函数委托需要将初始化的代理作为参数;否则,这种包装方法将是毫无意义的。

public static TResult ExecuteAndReturn<TProxy, TResult>(
    Func<TProxy, TResult> delegateToExecute) 
{ 
    string endpointUri = ServiceEndpoints.GetServiceEndpoint(typeof(TProxy)); 

    TResult valueToReturn; 

    using (ChannelFactory<TProxy> factory = new ChannelFactory<TProxy>(new BasicHttpBinding(), new EndpointAddress(endpointUri))) 
    { 
     TProxy proxy = factory.CreateChannel(); 

     valueToReturn = delegateToExecute(proxy); 
    } 

    return valueToReturn; 
} 

编辑:出现编译器错误,因为(IMyService x) => x.Foo()不与Func<T>委托兼容。在编写匿名函数时,推断类型是匿名函数本身的类型,而不是它所调用的方法。在这种情况下,匿名函数接受类型为IMyService的单个参数,并返回object(作为返回类型Foo)。因此,这个匿名方法的正确委托将是Func<IMyService, object>

+1

当然......感谢好的变量名称! :) – PoweredByOrange

+1

我相信我实际上已经写了一些非常类似于这个包装方法,所以它感到熟悉;-) – Douglas

0

你已经为你的说法是func<x>即不带参数的委托,但然后调用它作为Func<x,y>即委托,它需要1个参数,IMyService,因此错误“委托‘IMyService’不拿1个参数”