Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#:WCF:接口继承和转换问题_C#_Wcf_Inheritance_Interface_Compiler Errors - Fatal编程技术网

C#:WCF:接口继承和转换问题

C#:WCF:接口继承和转换问题,c#,wcf,inheritance,interface,compiler-errors,C#,Wcf,Inheritance,Interface,Compiler Errors,我正在为WCF服务编写客户端,该服务支持同步和异步调用,而无需在通道中为合同中的每个方法实现5-6个不同的方法 我有一个基本接口(IServiceClient)和一个基于此接口类型的泛型类(ServiceClient),如下所示: public interface IServiceClient { /* nothing here -- just for casting purpose */ } public abstract class ServiceClient<TChannel>

我正在为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(...);
        }
    }
}
[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 });
    }

    ....
}
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) { .... }
}
公共接口IServiceClient{/*此处无任何内容--仅用于强制转换目的*/}
公共抽象类ServiceClient:ClientBase,其中TChannel:class,IServiceClient
{
....
公共T SyncCall(字符串方法,对象[]args)
{
....
返回(T)。。。
}
公共服务调用异步调用(字符串方法,对象[]args)
{
返回新的ServiceCall(此、方法、参数);
}
....
公共类服务呼叫
{
公共服务调用(RemoteServiceClient服务,字符串方法,对象[]args)
{
...
}
...
public PageAsyncTask CreatePageAsyncTask(操作成功,操作失败)
{
返回新的System.Web.UI.PageAsyncTask(…);
}
}
}
另外,还有另一个接口(实际契约)扩展基本接口,并基于派生接口实现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(...);
        }
    }
}
[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 });
    }

    ....
}
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) { .... }
}
[服务合同]
公共接口IMyServiceClient:IServiceClient
{
....
[经营合同]
字符串getwhere(int索引);
[经营合同]
IAsyncResult BeginGetWhatever(int索引、System.AsyncCallback回调、object asyncState);
字符串ENDGETWHERTH(System.IAsyncResult结果);
....
}
公共部分类MyServiceClient:ServiceClient
{
....
公共字符串getwhere(int索引)
{
返回SyncCall(“getwhere”,新对象[]{index});
}
公共服务调用GetWhateverAsync(int索引)
{
返回AsyncCall(“getWhather”,新对象[]{index});
}
....
}
我尝试在控件中异步调用getWhather(int)方法,如下所示:

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(...);
        }
    }
}
[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 });
    }

    ....
}
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) { .... }
}
公共类MyWebControl:WebControl
{
私有无效句柄失败(System.Exception e){….}
public void CallService(ServiceClient.ServiceCall func,System.Action onSuccess,System.Action onFailure)
{
this.Page.RegisterAsyncTask(funct.CreatePageAsyncTask(onSuccess,onFailure??(e=>this.HandleFailure(e));
}
受保护的覆盖无效OnPreRender(EventArgs e)
{
基于预渲染(e);
....
var client=newmyserviceclient(/*whatever*/);
client.Open();
CallService(client.GetWhateverAsync(index)、this.OnResult、this.OnError);
....
}
公共void OnResult(字符串结果){….}
公共无效OnError(例外情况e){….}
}
我发现两个编译错误:

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>'
错误1“MyWebControl.CallService>(IServiceClient>.ServiceCall,System.Action,System.Action)”的最佳重载方法匹配具有一些无效参数
错误2参数1:无法从“ServiceClient.ServiceCall”转换为“ServiceClient.ServiceCall”
显然,编译器似乎无法理解IMyServiceClient扩展了IServiceClient。我知道接口继承不像类继承那样工作;但我不知道如何解决这个编译器错误。我已经尝试在MyServiceClient类中添加一个新的ServiceCall实现,以在base中扩展它——但是编译器错误没有改变

顺便说一句,如果我将我的ServiceClient实现更改为基于IMyServiceClient,它就会工作。另外,只调用client.getwhater(index)(调用SyncCall方法)编译并运行良好


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

通过更改我控制中的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)))); 
} 
public void CallService(ServiceClient.ServiceCall func,System.Action onSuccess,System.Action onFailure),其中TChannel:class,IServiceClient
{ 
this.Page.RegisterAsyncTask(funct.CreatePageAsyncTask(onSuccess,onFailure??(e=>this.HandleFailure(e));
} 

Thx.

这个问题与接口继承无关。事实上,泛型通常是不协变的:
ServiceClient
不能强制转换为
ServiceClient
,即使
IMyServiceClient
继承自
IServiceClient

不用担心;我自己解决了!太好了-那就接受你自己的答案吧,这样人们就不会一直看着它试图回答了!:)