2009-04-09 44 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); 
} 
相关问题