2009-04-09 82 views
2

我想創建一個委託,並且可以用來調用任意數量的Web服務,我的應用程序需要一個方法:C#委託可以使用對象類型更通用嗎?

例子:

public DateCheckResponseGetDate(DateCheckRequest requestParameters) 
{ 
    delegate object WebMethodToCall(object methodObject); 

    WebMethodToCall getTheDate = new WebMethodToCall(WebServices.GetTheDate); 

    return (DateCheckResponse)CallWebMethod(getTheDate , requestParameters); 
} 

public TimeCheckResponse GetTime(TimeCheckRequest requestParameters) 
{ 
    delegate object WebMethodToCall(object methodObject); 

    WebMethodToCall getTheTime = new WebMethodToCall(WebServices.GetTheTime); 

    return (TimeCheckResponse)CallWebMethod(getTheTime, requestParameters); 
} 

private object CallWebMethod(WebMethodToCall method, object methodObject) 
{ 
    return method(methodObject); 
} 

但不幸的是,當我嘗試編譯,我得到這些錯誤:

沒有重載 'GetTheDate' 匹配委託 'WebMethodToCall' 沒有重載 'GetTheTime' 匹配委託 'WebMethodToCall'

看來代表應該工作。

WebServices.GetTheDate和WebServices.GetTheTime都採用一個參數(分別爲DateCheckRequest和TimeCheckRequest)並且都返回一個值。

所以委託沒有匹配兩個Web方法的簽名? (從對象派生的接受和返回類型)。

是否有可能使用對象類型在.NET 2.0中創建一個非常可重用的委託?

回答

5

我建議你使用一個通用的委託,如Func<T, TResult>

public DateCheckResponseGetDate(DateCheckRequest requestParameters) 
{ 
    // Split declaration/assignment just to avoid wrapping 
    Func<DateCheckRequest, DateCheckResponse> method; 
    method = WebServices.GetTheDate; 
    return CallWebMethod(method, requestParameters); 
} 

你'd then then CallWebMethod generic:

public TResponse CallWebMethod<TRequest, TResponse> 
    (Func<TRequest, TResponse> method, TRequest request) 
{ 
    // Whatever you do in here. 
} 
7

我建議你改變你的代碼是這樣的:


public DateCheckResponseGetDate(DateCheckRequest requestParameters) 
{ 
    Func<DateCheckRequest, DateCheckResponse> getTheDate = new Func<DateCheckRequest, DateCheckResponse>(WebServices.GetTheDate); 

    return CallWebMethod(getTheDate , requestParameters); 
} 

//DEFINE CallWebMethod ADEQUATELY! 
public T CallWebMethod<T,U> (Func<T,U> webMethod, U arg) 
{ 
    return webMethod(arg); 
} 

這樣就可以避開所有醜陋的向下轉換:)

+0

不幸的是,我被困在.NET 2.0中,所以你的解決方案不適合我。 – 2009-04-09 15:29:13

+0

.NET 2.0支持泛型 – 2009-04-09 15:31:13

+0

不錯,但是,在.NET 3.5中添加了LINQ的Func。 – Andy 2009-04-09 15:32:48

1

是的,但你不得不重寫Web服務。 GetTheData和GetTheTime獲取對象,或提供獲取對象的重載。

這是因爲您無法隱式地在.NET中向上傳對象。換句話說,你可以這樣做:

TimeCheckRequest myTimeCheckRequest; 
object foo = myTimeCheckRequest; 

,但你不能做到這一點:

object myTimeCheckRequest; 
TimeCheckRequest foo = myTimeCheckRequest; 
-1

更新:可能不再有效嗎?不知道,我做這在C#2.0

爲了擴大對威爾的答案,而.NET不會爲你做這個隱含您可以通過添加一個隱含的操作您TimeCheckRequest類迫使它:

public class TimeCheckRequest 
{ 
    ... 

    public static implicit operator TimeCheckRequest(object request) 
    { 
     return (TimeCheckRequest) request; 
    } 
} 

我會不是推薦這個,但是,因爲您可以使用generic delegate而不是所有鑄造的性能成本。

0

可以定義Func鍵爲:

public delegate TResult Func<T, TResult>(T arg); 

這個定義需要什麼,不提供.NET 2.0,並添加到剪斷我上面張貼解決您的問題:)

2

我的工作它感謝這裏的評論。

private delegate object WebMethodToCall<T>(T methodObject); 

public DateCheckResponseGetDate(DateCheckRequest requestParameters) 
{ 
    WebMethodToCall<DateCheckRequest> getTheDate = new WebMethodToCall<DateCheckRequest>(WebServices.GetTheDate); 

    return CallWebMethod<DateCheckResponse, DateCheckRequest>(getTheDate, requestParameters); 
} 

public TimeCheckResponse GetTime(TimeCheckRequest requestParameters) 
{ 
    WebMethodToCall<TimeCheckRequest> getTheTime = new WebMethodToCall<TimeCheckRequest>(WebServices.GetTheTime); 

    return CallWebMethod<TimeCheckResponse, TimeCheckRequest>(getTheTime, requestParameters); 
} 

private T CallWebMethod<T, U>(WebMethodToCall<U> method, U methodObject) 
{ 
    return (T)method(methodObject); 
} 
相關問題