一个C#代表可以使用对象类型更通用的?
-
09-09-2019 - |
题
我想创建一个委托,并且可以用来调用任意数量的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?
解决方案
我建议您使用泛型委托如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.
}
其他提示
我建议你改变你的代码是这样的:
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);
}
此方式可以避免所有的丑陋向下转换的:)
我的工作了感谢这里的评论。
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);
}
是的,但你必须重写WebServices.GetTheData和GetTheTime采取的对象,或者提供需要的对象重载。
这是因为你不能的上溯造型的在.NET对象含蓄。换句话说,你可以这样做:
TimeCheckRequest myTimeCheckRequest;
object foo = myTimeCheckRequest;
但你不能做到这一点:
object myTimeCheckRequest;
TimeCheckRequest foo = myTimeCheckRequest;
您可以定义函数功能为:
public delegate TResult Func<T, TResult>(T arg);
这个定义需要什么,这不是在.NET 2.0中提供并添加到剪断我上面张贴解决您的问题:)
更新: 可能不再有效?不知道,我这样做在C#2.0
要扩大威尔的答案,而.NET不会为你做这个隐含您可以通过添加一个隐含的操作您TimeCheckRequest类迫使它:
public class TimeCheckRequest
{
...
public static implicit operator TimeCheckRequest(object request)
{
return (TimeCheckRequest) request;
}
}
我会的不可以建议这一点,但是,因为你可以使用的泛型委托而不是没有所有的铸造性能成本。
不隶属于 StackOverflow