2010-07-14 55 views
0

我正在为支持同步和异步调用的WCF服务编写客户端,而无需在合同中的每个方法的通道中实现5-6种不同的方法。C#:WCF:接口继承和铸造问题

我有一个基本接口(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方法)编译和工作就好了。

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

+0

无后顾之忧;自己解决吧! – user392005 2010-07-14 23:06:49

+0

伟大 - 接受你自己的答案然后人们不会继续看着它试图回答! :) – nitzmahone 2010-07-16 03:37:27

回答

0

在我的控制改变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)))); 
} 

THX。

1

该问题与接口继承无关。一般来说,泛型不是covariantServiceClient<IMyServiceClient>不能转换为ServiceClient<IServiceClient>,即使IMyServiceClient继承自IServiceClient