I would like to create a delegate and a method that can be used to call any number of Web services that my application requires:
我想创建一个委托和一个方法,可用于调用我的应用程序所需的任意数量的Web服务:
Example:
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);
}
But, unfortunately, when I try to compile, I get these errors:
但是,不幸的是,当我尝试编译时,我收到了以下错误:
No overload for 'GetTheDate' matches delegate 'WebMethodToCall' No overload for 'GetTheTime' matches delegate 'WebMethodToCall'
“GetTheDate”没有重载匹配委托“WebMethodToCall”'GetTheTime'没有重载匹配委托'WebMethodToCall'
It seems like the delegate should work.
似乎代表应该工作。
WebServices.GetTheDate and WebServices.GetTheTime both take a single parameter (DateCheckRequest and TimeCheckRequest, respectively) and both return a value.
WebServices.GetTheDate和WebServices.GetTheTime都采用单个参数(分别为DateCheckRequest和TimeCheckRequest)并且都返回一个值。
So doesn't the delegate match the signature of the two web methods? (both accept and return types derived from object).
那么委托不匹配两个Web方法的签名吗? (接受和返回从对象派生的类型)。
Is it possible to use the object type to make a very reusable delegate in .NET 2.0?
是否可以使用对象类型在.NET 2.0中创建一个非常可重用的委托?
6 个解决方案
#1
I suggest you use a generic delegate such as Func<T, TResult>
:
我建议你使用泛型委托,如Func
public DateCheckResponseGetDate(DateCheckRequest requestParameters)
{
// Split declaration/assignment just to avoid wrapping
Func<DateCheckRequest, DateCheckResponse> method;
method = WebServices.GetTheDate;
return CallWebMethod(method, requestParameters);
}
You'd then make CallWebMethod
generic too:
然后你也可以调用CallWebMethod:
public TResponse CallWebMethod<TRequest, TResponse>
(Func<TRequest, TResponse> method, TRequest request)
{
// Whatever you do in here.
}
#2
I'd suggest you change your code to something like:
我建议你将代码更改为:
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);
}
This way you can avoid all of the ugly downcasting :)
这样你可以避免所有丑陋的向下转换:)
#3
I worked it out thanks to the comments here.
由于这里的评论我把它解决了。
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);
}
#4
Yes, but you'd have to rewrite WebServices.GetTheData and GetTheTime to take objects, or provide overloads that take objects.
是的,但您必须重写WebServices.GetTheData和GetTheTime来获取对象,或者提供带有对象的重载。
This is because you can't upcast objects in .NET implicitly. In other words, you can do this:
这是因为您无法隐式地在.NET中向上转换对象。换句话说,你可以这样做:
TimeCheckRequest myTimeCheckRequest;
object foo = myTimeCheckRequest;
but you can't do this:
但你不能这样做:
object myTimeCheckRequest;
TimeCheckRequest foo = myTimeCheckRequest;
#5
You may define Func as:
您可以将Func定义为:
public delegate TResult Func<T, TResult>(T arg);
This definition requires nothing that's not available in .NET 2.0 and added to the snipped I've posted above solves your problem :)
这个定义只需要在.NET 2.0中没有的东西,并添加到上面发布的剪辑中解决了你的问题:)
#6
UPDATE: May no longer be valid? Dunno, I've done this in C# 2.0
更新:可能不再有效? Dunno,我在C#2.0中完成了这个
To expand on Will's answer, while .NET will not do this for you implicitly you can force it by adding an implicit operator to your TimeCheckRequest class:
为了扩展Will的答案,虽然.NET不会隐式地为你做这个,你可以通过向TimeCheckRequest类添加一个隐式运算符来强制它:
public class TimeCheckRequest
{
...
public static implicit operator TimeCheckRequest(object request)
{
return (TimeCheckRequest) request;
}
}
I would not recommend this, however, since you can use a generic delegate instead without the performance cost of all the casting.
但是,我不建议这样做,因为您可以使用通用委托而不需要所有转换的性能成本。
#1
I suggest you use a generic delegate such as Func<T, TResult>
:
我建议你使用泛型委托,如Func
public DateCheckResponseGetDate(DateCheckRequest requestParameters)
{
// Split declaration/assignment just to avoid wrapping
Func<DateCheckRequest, DateCheckResponse> method;
method = WebServices.GetTheDate;
return CallWebMethod(method, requestParameters);
}
You'd then make CallWebMethod
generic too:
然后你也可以调用CallWebMethod:
public TResponse CallWebMethod<TRequest, TResponse>
(Func<TRequest, TResponse> method, TRequest request)
{
// Whatever you do in here.
}
#2
I'd suggest you change your code to something like:
我建议你将代码更改为:
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);
}
This way you can avoid all of the ugly downcasting :)
这样你可以避免所有丑陋的向下转换:)
#3
I worked it out thanks to the comments here.
由于这里的评论我把它解决了。
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);
}
#4
Yes, but you'd have to rewrite WebServices.GetTheData and GetTheTime to take objects, or provide overloads that take objects.
是的,但您必须重写WebServices.GetTheData和GetTheTime来获取对象,或者提供带有对象的重载。
This is because you can't upcast objects in .NET implicitly. In other words, you can do this:
这是因为您无法隐式地在.NET中向上转换对象。换句话说,你可以这样做:
TimeCheckRequest myTimeCheckRequest;
object foo = myTimeCheckRequest;
but you can't do this:
但你不能这样做:
object myTimeCheckRequest;
TimeCheckRequest foo = myTimeCheckRequest;
#5
You may define Func as:
您可以将Func定义为:
public delegate TResult Func<T, TResult>(T arg);
This definition requires nothing that's not available in .NET 2.0 and added to the snipped I've posted above solves your problem :)
这个定义只需要在.NET 2.0中没有的东西,并添加到上面发布的剪辑中解决了你的问题:)
#6
UPDATE: May no longer be valid? Dunno, I've done this in C# 2.0
更新:可能不再有效? Dunno,我在C#2.0中完成了这个
To expand on Will's answer, while .NET will not do this for you implicitly you can force it by adding an implicit operator to your TimeCheckRequest class:
为了扩展Will的答案,虽然.NET不会隐式地为你做这个,你可以通过向TimeCheckRequest类添加一个隐式运算符来强制它:
public class TimeCheckRequest
{
...
public static implicit operator TimeCheckRequest(object request)
{
return (TimeCheckRequest) request;
}
}
I would not recommend this, however, since you can use a generic delegate instead without the performance cost of all the casting.
但是,我不建议这样做,因为您可以使用通用委托而不需要所有转换的性能成本。