我正在爲支持同步和異步調用的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方法)編譯和工作就好了。
任何關於正在進行的或編譯器正在尋找什麼的想法都會有所幫助。謝謝。
無後顧之憂;自己解決吧! – user392005 2010-07-14 23:06:49
偉大 - 接受你自己的答案然後人們不會繼續看着它試圖回答! :) – nitzmahone 2010-07-16 03:37:27