我想创建一个委托和一个方法,可用于调用我的应用程序所需的任意数量的Web服务:
示例:
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中创建一个非常可重用的委托?
答案 0 :(得分: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);
}
这样你可以避免所有丑陋的向下转换:)
答案 1 :(得分: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);
}
然后你也可以CallWebMethod
通用:
public TResponse CallWebMethod<TRequest, TResponse>
(Func<TRequest, TResponse> method, TRequest request)
{
// Whatever you do in here.
}
答案 2 :(得分: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);
}
答案 3 :(得分:1)
是的,但你必须重写WebServices.GetTheData和GetTheTime来获取对象,或提供带对象的重载。
这是因为您无法隐式地在.NET中 upcast 对象。换句话说,你可以这样做:
TimeCheckRequest myTimeCheckRequest;
object foo = myTimeCheckRequest;
但你不能这样做:
object myTimeCheckRequest;
TimeCheckRequest foo = myTimeCheckRequest;
答案 4 :(得分:0)
您可以将Func定义为:
public delegate TResult Func<T, TResult>(T arg);
此定义不需要.NET 2.0中没有的任何内容,并添加到我上面发布的剪辑中解决了您的问题:)
答案 5 :(得分:-1)
更新: 可能不再有效? Dunno,我在C#2.0
中完成了这个要扩展Will的答案,而.NET不会隐式执行此操作,您可以通过向TimeCheckRequest类添加隐式运算符来强制执行此操作:
public class TimeCheckRequest
{
...
public static implicit operator TimeCheckRequest(object request)
{
return (TimeCheckRequest) request;
}
}
我会不推荐这个,因为你可以使用generic delegate而不需要所有演员的演出费用。