对不起,如果这是一个骗局,但我似乎无法获得正确的关键字组合来过滤各种类型约束和泛型问题(因为有很多)。

我有两个接口——我们称它们为 在线离线.

它们密切相关,因为它们描述了几乎相同的合约,但它们之间的主要区别之一是使用具体实现的上下文。这不完全是我的情况,但它很好地说明了问题。

然后,我有一些方法可以针对这些接口的具体实现者起作用。有时这些方法只想处理一种类型,而不处理另一种类型。

足够简单:

public void DoStuff<T>(string foo) where T : IOnline {}

关键在于实现可以在任一类型上操作的方法的代码。我认为这是正确的,但在阅读编译错误时,我期望约束将被解释为“如果它们实现 IOnline 或 IOffline,则允许在此处通用使用任何类型 T”,实际上被解释为“允许任何类型如果它们同时实现“T”,则此处通用。

public void DoStuff<T>(string foo) where T : IOnline, IOffline {}

尝试实现两个具有相同名称但不同约束的单独方法会失败,因为存在明显的歧义问题——我们没有重载,因为参数列表是相同的(因为所需的行为是相同的)。

可以 对两种不同的方法使用两个不同的名称,每种方法都有适当的约束,但这看起来很笨拙,并使下游的其他事情变得很痛苦......可行,但并不理想。

我觉得这里一定有什么东西我错过了......我在普通土地上感觉非常舒服,但这是我第一次必须完成我所追求的事情,我觉得我只是在旋转我的轮子。

有帮助吗?

解决方案

正如第二个示例中那样提供多个约束确实是相加的。这 有关通用约束的 MSDN 页面 有一点关于这个。

您能否使两个接口继承自基接口,并将方法限制为基类型?

其他提示

这可能不是您问题的答案,但我自然而然地感觉到您可能想要重构您的界面。从你的问题来看:

它们密切相关,因为它们描述了几乎相同的合同,但是它们之间的关键区别之一是使用具体实现的背景。

我对接口的看法是 他们是合同. 。他们定义了某事应该如何 , ,不完全是应该的 表现;这就是执行的任务。现在,我没有关于您的应用程序或问题域的信息,但我可能会尝试花一些时间来识别这些接口的相同部分并将它们移动到单个接口中,并且仅将差异保留为单独的接口。这样您也许可以更轻松地解决此类问题。

我认为 .NET 中执行此操作的标准方法是拥有一个包含 IOnline 和 IOffline 函数的接口,然后是一些属性,说明哪些函数实际上在特定类中实现。您可以在 .NET 中的各个位置看到这种模式,其中包括可能实现也可能未实现的 Seek() 方法以及可以测试的 CanSeek 属性。

它也许不是最简洁的面向对象设计,但它确实有效。

丢失了一些编译时检查,但我看不到任何解决方法......你必须选择你更愿意使用的,(我假设你的偏好是在线的):

public void DoStuff<T>(string foo)
{
    Type type = typeof(T);
    if(type.GetInterfaces().Contains(typeof(IOnline)))
         doStuffOnline<T>(foo);
    else if(type.GetInterfaces().Contains(typeof(IOffline)))
         doStuffOffline<T>(foo);
    else
         throw new Exception("T must implement either IOnline or IOffline");
}

private void doStuffOnline<T>(string foo){ // can assume T : IOnline }
private void doStuffOffline<T>(string foo){ // can assume T : IOffline }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top