是否可以将通用T2
限制为而不是为T1
或其任何子类?
我有以下两种方法重载:
Sub Foo(Of T1, T2)(arg1 As T1, arg2 As T2) ' 1
Sub Foo(Of T)(arg1 As T, arg2 As T) ' 2
我可以以任何方式定义这些方法,以便这些代码行解析为
Foo(1, True) ' 1
Foo(1, 1) ' 2
目前,除非我明确写
,否则第二次调用是不明确的Foo(1, True)
Foo(Of Integer)(1, 1)
类型约束(Of T1, T2 As T1)
允许我将T2
限制为T1
及其子类。但是我可以编写任何内容来实现相反的目的,这样第一次重载只会匹配T2
不是 T1
(或者它的任何子类,但是那个' s甚至与我无关)?
我可以保证,在我的情况下T1
和T2
永远不会在任何方向上继承或转换。它们是大约一千个类的池中的任意两个,这就是为什么我不能创建所有类型的非泛型交叉产品的原因。
答案 0 :(得分:1)
您需要的东西似乎不可能,因为任何限制都是针对单个参数而不是组合。 有一个解决方案在运行时而不是在编译时决定。
您想要:
Sub Foo(Of T1, T2)(arg1 As T1, arg2 As T2)
Do1()
End Sub
Sub Foo(Of T)(arg1 As T, arg2 As T)
Do2()
End Sub
您可以:
Sub Foo(Of T1, T2)(arg1 As T1, arg2 As T2)
If arg1.GetType() is arg2.GetType() Then
Do2()
else
Do1()
End If
End Sub
这不是很好,但有点慢,但解决了问题。
答案 1 :(得分:1)
就我而言,我的目标是通过使用两个泛型标记Obsolete
来禁止使用两个不同类型的参数。我实际上通过使用扩展程序找到了一种方法:
Public Class Bar
Public Sub Foo(Of T)(arg1 As T, arg2 As T)
DoStuff()
End Sub
End Class
Public Module BarExtensions
<Obsolete("A good explanation of what's wrong", True)>
<Extension>
Public Sub Foo(Of T1, T2)(bar As Bar, arg1 As T1, arg2 As T2)
' I could make this work, but any code calling this is most likely wrong
Throw New ArgumentException()
End Sub
End Module
这允许我警告用户他们的代码有些可疑:
Public Class Baz
Public Sub WrongCodeDoingDangerousThings(bar As Bar)
Dim x1 As Double = 1d
Dim x2 As Double = 2d
Dim x3 As Integer = 3
bar.Foo(x1, x2) ' OK, no resolve conflict
bar.Foo(x1, x3) ' Won't compile with "A good explanation of what's wrong"
' This works because conflicts between an extension and an instance
' method are automatically resolved in favor of the instance method
End Sub
End Class