【问题标题】:Can I avoid the typecasting of interface method parameters to concrete types for same family of classes?我可以避免将接口方法参数类型转换为同一系列类的具体类型吗?
【发布时间】:2019-08-20 16:58:26
【问题描述】:

我有3个接口大致如下: IData 环绕所需数据 IDataInfo 以提供有关 IData 和

的元数据
IDataProvider
{
   IData GetData(IDataInfo iDataInfo);
}

对于上述接口,我有几个派生接口系列。例如:

  1. IBikeData : IData、IBikeDataInfo : IDataInfo 和 IBikeDataProvider : IDataProvider
  2. ICarData : IData、ICarDataInfo : IDataInfo 和 ICarDataProvider : IDataProvider 等等。

现在,在IBikeDataProvider 和ICarDataProvider 的IData GetData(IDataInfo iDataInfo) 的具体实现中,我需要将传入的iDataInfo 参数类型转换为各自的派生类型(IBikeDataInfo 和ICarDataInfo),以便其他访问其他特定功能。我对每个具体实现中的这种类型转换有点不舒服,我认为这是不正确的做法。有没有办法可以重构我的设计来防止这种情况发生?

【问题讨论】:

  • 具体类不应以 I 开头 - 通常表示接口。
  • 如果您的实现需要特定类型,则不应将其定义为采用接口。为您所引用的接口和类提供示例代码也可能更有帮助,尤其是显示您想要避免的强制转换操作的代码。
  • 很抱歉将它们作为具体类型提及。它们基本上是派生接口,将由各自的类具体化。
  • 我想要接口,因为有另一个模块,比如调度程序,我需要在不知道实际类型的情况下以相同的方式处理几个派生的接口系列。

标签: java c# interface polymorphism refactoring


【解决方案1】:

假设您可以调整IDataProvider 接口,似乎泛型将是这里的答案。如果您将逆变和协变类型参数与您的 IData 和 IDataInfo 类型相一致,则可以将定义向上切换以获得如下内容:

public interface IDataProvider<in TIn, out TOut> where TIn : IDataInfo 
                                                 where TOut : IData 
{
    TOut GetData(TIn dataInfo);
}

您的IBikeDataProvider 接口可以声明如下:

public interface IBikeDataProvider : IDataProvider<IBikeDataInfo, IBikeData> { }

这将导致以下具体的类实例:

public class BikeDataProvider : IBikeDataProvider
{
    public IBikeData GetData(IBikeDataInfo dataInfo)
    {
        // Do things
    }
}

【讨论】:

  • 我想以类似的方式使用模块中的基本接口(例如调度程序)来处理所有系列。如果是这种情况,上述解决方案是否可行?因为,我需要用于实例化和使用派生接口和类系列的类型。
  • @SanthoshKumar 不,你不能这样做。这是我能想到的类型安全选项,但为了保证类型安全,您必须在编译时提供一些类型据我所知。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-23
  • 2022-07-31
  • 1970-01-01
  • 2020-10-27
相关资源
最近更新 更多