我想创建一个委托,并且可以用来调用任意数量的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;
    }
}

我会的不可以建议这一点,但是,因为你可以使用的泛型委托而不是没有所有的铸造性能成本。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top