打扰一下,如果这是一个骗局,但我似乎无法得到正确的关键词组合来过滤各种类型约束和泛型问题(因为有很多)。
我有两个接口 - 我们称之为 IOnline 和 IOffline 。
它们密切相关,因为它们描述了几乎相同的合同,但它们之间的关键差异之一是将使用具体实现的上下文。这不完全是我的情况,但它很好地说明了问题。
然后我有一些方法可以对付这些接口的具体实现者。有时这些方法只想处理一种类型而不是另一种类型。
足够简单:
public void DoStuff<T>(string foo) where T : IOnline {}
kicker正在实现可以在EITHER类型上运行的方法的代码。我认为这是正确的,但在阅读编译错误时,我期望约束将被解释为“允许任何类型T在这里一般使用,如果它们实现IOnline OR IOffline”,实际上被解释为“允许任何类型”如果它们实现两种,那么这里通常使用T.“。
public void DoStuff<T>(string foo) where T : IOnline, IOffline {}
尝试实现具有相同名称但不同约束的两个单独方法失败,因为存在明显的歧义问题 - 我们没有超载,因为参数列表是相同的(因为期望的行为是相同的)。
我可以为两个不同的方法使用两个不同的名称,每个方法都有适当的约束,但这看起来很糟糕,并使下游的其他事情成为屁股中的痛苦......可行,但不是理想的。
我觉得这里肯定会有一些我想念的东西......我觉得在通用土地上感觉非常舒服,但这是我第一次完成我所追求的目标而且我觉得我是只是旋转我的车轮atm。
答案 0 :(得分:8)
在第二个例子中提供多个约束确实是附加的。 MSDN page on generic constraints对此有一点了解。
您可以使两个接口继承自基接口,并将方法约束为基类型吗?
答案 1 :(得分:2)
这可能不是你问题的答案,但我自发地感觉你可能想要重构你的界面。从你的问题:
他们与他们密切相关 描述几乎相同的合同, 但是其中一个关键的区别 他们是在其中的背景 将使用具体的实现。
我对界面的看法是它们是合同。它们定义了看起来的内容,而不是行为的确切内容。这是实施的任务。现在,我没有关于您的应用程序或问题域的信息,但我可能会尝试花一些时间来识别这些接口的相同部分并将它们移动到单个接口中,并且只将差异保留为单独的接口。通过这种方式,您可以更轻松地浏览这些问题。
答案 2 :(得分:0)
我认为在.NET中执行此操作的标准方法是使用一个包含IOnline和IOffline函数的接口,然后使用一些属性来说明哪些函数实际在特定类中实现。您可以在.NET中的各个位置看到此模式,其中包含可能实现或可能未实现的Seek()方法以及可以测试的CanSeek属性。
它可能不是最干净的OO设计,但它有效。
答案 3 :(得分:0)
丢失了一些编译时检查,但我看不到任何方法...你必须选择你更愿意使用的,(我假设你的偏好会在线):
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 }