c# - 接受两个接口(interface)之一的方法

标签 c# .net

问题

我有两个接口(interface) IImporterIExporter 以及一个处理这些接口(interface)实例的类:

class IoManager
{
    public ReadOnlyCollection<IImporter> Importers { get; } 
    public ReadOnlyCollection<IExporter> Exporters { get; }

    // ...
}

在这个类中,我想实现一个方法Add(...),它可以添加一个导入器或一个导出器。

我知道我可以为两个接口(interface)创建一个重载

public void Add(IExporter exporter);
public void Add(IImporter importer);

问题是,如果我想通过 Add(...) 函数添加一个实现两个接口(interface)的对象,例如 CsvIo : IImporter, IExporter,我会得到一个模棱两可的调用编译器错误,因为 CsvIo 被两个重载接受。

我不想做的事

  • 我不想将重载重命名为不同的名称,因为大多数类型都实现了这两个接口(interface),而且我希望实现 IExporterIImporter 或两者。
  • 我不想创建一个由两个接口(interface)实现的“父”接口(interface),因为这看起来像一个hacky解决方案
  • 我不想在 Add(...) 调用中转换类型,例如 Add((IImporter) CsvIoInstance),因为这表明只有使用这种类型的进口商。但是两个重载都会检查对象是否实现了两个接口(interface)并将其相应地添加到两个列表中。

问题

有没有办法以连贯的方式接受不同的类型(以便每种类型的调用看起来都一样)?

编辑

澄清我的实现:这是插件系统的一部分。我想添加多种方式来存储我的数据(以便它可以被其他应用程序使用)。 IExporter 接口(interface)用于存储数据,而IImporter 接口(interface)用于加载数据。 IoManager 管理所有已注册的插件。当然,一个类可能(并且可能很常见)同时实现某种文件格式的导出和导入。这就是为什么我希望 Add(...) 函数在所有情况下都相似。

但是,再次考虑(如评论中所述)插件仅在运行时已知,我认为这使得歧义成为一个过时的问题。所以这只与内置类型有关。

最佳答案

我想特别关注一句话:

I don't want to cast types in the Add(...) call, like Add((IImporter) CsvIoInstance), because that suggests that only the importer of this type is used. But both overloads check if the object implements both interfaces and adds it to both lists accordingly.

您当前的设计已经放弃了类型安全的目标之一:避免运行时类型检查。理想情况下,采用IImporter 参数的方法应该将该参数用作IImporter。这在方法的调用者和实现者之间形成了一种“契约”:实现者相信调用者会提供它需要的东西,而调用者相信实现者只会以这种方式使用它。 (另请参阅:Principle of least astonishment。)

假设您是此类的消费者。有一个 IImporter 集合和一个带有签名 Add(IImporter foo) 的方法。您希望该方法做什么? 希望它将 foo 添加到 IImporters 列表中 - 我希望它也做一些事情否则因为我的对象恰好实现了另一个接口(interface)(例如 IExporter)。以这种方式使用类型系统会“背叛”您与调用者建立的契约。

将您的方法名称更改为 AddImporterAddExporter,然后让每个方法将参数添加到相应的列表中。这解决了重载解析的问题,意味着调用者得到的正是他们所要求的。

关于c# - 接受两个接口(interface)之一的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47857257/

相关文章:

c# - 你如何将对象从 c# 传递给 lua 的函数?

c# - 比较两个日期时间 - 没有小时和秒

c# - 我能以更好的方式从 TcpClient 读取流吗?

c# - 如何在 C# 中对变量定义中的接口(interface)求和?

使用通配符证书通过 SSL 的 C# Web 服务调用 (asmx)

c# - 如何检查 PCL 项目 xamarin 中的服务器是否可达?

c# - 无法在 WebSocket 客户端中接收消息

c# - 如何衡量 .NET 中托管线程的性能

c# - 传递枚举命令行参数

c# - MVC中如何使用多个路由