C#委托可以使用对象类型更通用吗?
我想创建一个委托,并且可以用来调用任意数量的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中创建一个非常可重用的委托?
我建议你使用一个通用的委托,如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.
}
我建议你改变你的代码是这样的:
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);
}
这样就可以避开所有丑陋的向下转换:)
是的,但你不得不重写Web服务。 GetTheData和GetTheTime获取对象,或提供获取对象的重载。
这是因为您无法隐式地在.NET中向上传对象。换句话说,你可以这样做:
TimeCheckRequest myTimeCheckRequest;
object foo = myTimeCheckRequest;
,但你不能做到这一点:
object myTimeCheckRequest;
TimeCheckRequest foo = myTimeCheckRequest;
更新:可能不再有效吗?不知道,我做这在C#2.0
为了扩大对威尔的答案,而.NET不会为你做这个隐含您可以通过添加一个隐含的操作您TimeCheckRequest类迫使它:
public class TimeCheckRequest
{
...
public static implicit operator TimeCheckRequest(object request)
{
return (TimeCheckRequest) request;
}
}
我会不是推荐这个,但是,因为您可以使用generic delegate而不是所有铸造的性能成本。
可以定义Func键为:
public delegate TResult Func<T, TResult>(T arg);
这个定义需要什么,不提供.NET 2.0,并添加到剪断我上面张贴解决您的问题:)
我的工作它感谢这里的评论。
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);
}
不幸的是,我被困在.NET 2.0中,所以你的解决方案不适合我。 – 2009-04-09 15:29:13
.NET 2.0支持泛型 – 2009-04-09 15:31:13
不错,但是,在.NET 3.5中添加了LINQ的Func。 – Andy 2009-04-09 15:32:48