【问题标题】:C#: WCF: Interface inheritance and casting questionC#:WCF:接口继承和转换问题
【发布时间】:2010-07-14 20:42:04
【问题描述】:

我正在为一个同时支持同步和异步调用的 WCF 服务编写客户端,而不必为合约中的每个方法在通道中实现 5-6 种不同的方法。

我有一个基接口(IServiceClient)和一个基于这个接口类型的泛型类(ServiceClient)如下:

public interface IServiceClient { /* nothing here -- just for casting purpose */ }

public abstract class ServiceClient<TChannel> : ClientBase<TChannel> where TChannel : class, IServiceClient
{
    ....

    public T SyncCall<T>(string method, object[] args)
    {
        ....
        return (T)...
    }

    public ServiceCall<T> AsyncCall<T>(string method, object[] args)
    {
        return new ServiceCall<T>(this, method, args);
    }

    ....

    public class ServiceCall<T>
    {
        public ServiceCall(RemoteServiceClient<TChannel> service, string method, object[] args)
        {
            ...
        }

        ...

        public PageAsyncTask CreatePageAsyncTask(Action<T> onSuccess, Action<Exception> onFailure)
        {
            return new System.Web.UI.PageAsyncTask(...);
        }
    }
}

另外,还有另一个接口(实际契约)扩展基接口和基于派生接口的ServiceClient类的具体实现如下:

[ServiceContract]
public interface IMyServiceClient : IServiceClient
{
    ....

    [OperationContract]
    string GetWhatever(int index);
    [OperationContract]
    IAsyncResult BeginGetWhatever(int index, System.AsyncCallback callback, object asyncState);
    string EndGetWhatever(System.IAsyncResult result);

    ....
}


public partial class MyServiceClient : ServiceClient<IMyServiceClient>
{
    ....

    public string GetWhatever(int index)
    {
        return SyncCall<string>("GetWhatever", new object[] { index });
    }
    public ServiceCall<string> GetWhateverAsync(int index)
    {
        return AsyncCall<string>("GetWhatever", new object[] { index });
    }

    ....
}

我尝试在我的控件中异步调用 GetWhatever(int) 方法,如下所示:

public class MyWebControl : WebControl
{
    private void HandleFailure(System.Exception e) { .... }
    public void CallService<T>(ServiceClient<IServiceClient>.ServiceCall<T> func, System.Action<T> onSuccess, System.Action<Exception> onFailure)
    {
        this.Page.RegisterAsyncTask(func.CreatePageAsyncTask(onSuccess, onFailure ?? (e => this.HandleFailure(e))));
    }

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);

        ....

        var client = new MyServiceClient(/*whatever*/);
        client.Open();
        CallService(client.GetWhateverAsync(index), this.OnResult, this.OnError);

        ....
    }

    public void OnResult(string result) { .... }
    public void OnError(Exception e) { .... }
}

我得到 2 个编译错误:

Error 1 The best overloaded method match for 'MyWebControl.CallService<string>>(IServiceClient>.ServiceCall<string>, System.Action<string>, System.Action<System.Exception>)' has some invalid arguments
Error 2 Argument 1: cannot convert from 'ServiceClient<IMyServiceClient>.ServiceCall<string>' to 'ServiceClient<IServiceClient>.ServiceCall<string>'

显然编译器似乎无法确定 IMyServiceClient 扩展了 IServiceClient。我知道接口继承不像类继承那样工作;但我不确定如何解决此编译器错误。我已经尝试在 MyServiceClient 类中添加一个新的 ServiceCall 实现来扩展它的基础——但编译器错误没有改变。

顺便说一句,如果我将我的 ServiceClient 实现更改为基于 IMyServiceClient,它可以工作。此外,仅调用 client.GetWhatever(index)(调用 SyncCall 方法)编译并且工作正常。

任何关于正在发生的事情或编译器正在寻找什么的想法都会有所帮助。谢谢。

【问题讨论】:

  • 不用担心;自己解决了!
  • 太棒了-然后接受您自己的答案,这样人们就不会一直看着它试图回答! :)

标签: c# wcf inheritance interface compiler-errors


【解决方案1】:

这个问题与接口继承无关。事实上,一般来说,泛型不是协变的:ServiceClient&lt;IMyServiceClient&gt; 不能转换为 ServiceClient&lt;IServiceClient&gt;,即使 IMyServiceClient 继承自 IServiceClient。

【讨论】:

    【解决方案2】:

    通过更改我控件中的 CallService 方法来解决它:

    public void CallService<TChannel, T>(ServiceClient<TChannel>.ServiceCall<T> func, System.Action<T> onSuccess, System.Action<Exception> onFailure) where TChannel: class, IServiceClient
    { 
        this.Page.RegisterAsyncTask(func.CreatePageAsyncTask(onSuccess, onFailure ?? (e => this.HandleFailure(e)))); 
    } 
    

    谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-05
      • 1970-01-01
      • 2012-09-04
      • 1970-01-01
      • 2011-07-31
      • 2011-06-14
      相关资源
      最近更新 更多