在 C# 中聚合接口

本文关键字:接口 | 更新日期: 2023-09-27 17:56:50

我有这个类:

class UrlManagementServiceClient : System.ServiceModel.ClientBase<IUrlManagementService>, IUrlManagementService

客户群实现IDisposableICommunicationObject。我也有这个界面:

interface IUrlManagementProxy : IUrlManagementService, ICommunicationObject, IDisposable

但我不能UrlManagementServiceClient对象投射到IUrlManagementProxy.有没有办法做到这一点?我想得到一个可以访问所有三个接口上的所有方法的对象。

在 C# 中聚合接口

您只能强制转换为继承自的接口,以便能够强制转换为需要实现该接口IUrlManagementProxy

class UrlManagementServiceClient :
   System.ServiceModel.ClientBase<IUrlManagementService>, IUrlManagementProxy

然后,您可以将UrlManagementServiceClient转换为 UrlManagementProxyIUrlManagementServiceICommunicationObjectIDisposable

编辑
WCF 生成的类是部分的,这意味着您可以在另一个文件中扩展类定义。放

public partial class UrlManagementServiceClient : IUrlManagementProxy {}

在另一个代码文件中,您的类也将实现您的完整IUrlManagementProxy接口,然后您可以将其转换为 IUrlManagementProxy

使UrlManagementServiceClient实现IUrlManagementProxy而不是IUrlManagementService

class UrlManagementServiceClient : System.ServiceModel.ClientBase<IUrlManagementProxy>, IUrlManagementProxy

您需要在UrlManagementServiceClient上实现IUrlManagementProxy。没有其他方法——它是一个单独的类型。

显然,您不能将对象强制转换为它未实现的接口。

但是,您可以做的(如果从UrlManagementServiceClient实例中为每个接口实现所有方法有意义)是将您的UrlManagementServiceClient包装在实现所需接口的对象中。

这称为装饰器模式(而不是代理)。代理通常"看起来"是底层对象,而在这种情况下,您正在添加客户端没有的功能。

换句话说,您将需要一个新类:

public class UrlManagementClientProxy : IUrlManagementProxy 
{
     // we need a reference to the underlying client
     private readonly UrlManagementServiceClient _client;
     // underlying client is passed to the proxy in constructor
     public UrlManagementClientProxy(UrlManagementServiceClient client)
     {
         _client = client;
     }
     #region IUrlManagementProxy methods
     // you implementation goes here. if the underlying client
     // already implements a certain method, then you just need
     // to pass the call 
     // for example, client already implements methods
     // from the IUrlManagementService interface, so use them
     public string GetUrl() // made up
     {
          return _client.GetUrl();
     }
     #endregion
}

这允许您重用客户端的实现,并在其上添加其他功能。

为了解决这个问题,我只是扩展了类并在其上声明了聚合接口:

public class UrlManagementProxy : UrlManagementServiceClient, IUrlManagementProxy
{
    public UrlManagementProxy(Binding binding, EndpointAddress remoteAddress)
        : base(binding, remoteAddress)
    {
    }
}

然后我用UrlManagementProxy而不是UrlManagementServiceClient.

我只需要通过我需要的构造函数。其余的都是自动处理的。同样这样,我不需要修改UrlManagementServiceClient,因此我可以重新生成它,一切仍然可以正常工作。