将泛型类型参数限制为不是VB.NET中的另一个泛型类型参数

时间:2017-11-22 20:54:38

标签: vb.net

是否可以将通用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甚至与我无关)?

我可以保证,在我的情况下T1T2永远不会在任何方向上继承或转换。它们是大约一千个类的池中的任意两个,这就是为什么我不能创建所有类型的非泛型交叉产品的原因。

2 个答案:

答案 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