2013-07-04 93 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個參數」