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

限制泛型类型参数不是VB.NET中的另一个泛型类型参数,vb.net,Vb.net,是否可以将泛型T2限制为notbeT1或其任何子类 我有以下两个方法重载: 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)

是否可以将泛型
T2
限制为notbe
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)
类型约束
(T1,T2为T1)
允许我将
T2
限制为
T1
及其子类。但是我可以写任何东西来实现相反的效果吗,这样第一个重载只在
T2
不是
T1
时匹配(或者它的任何子类,但这对我来说都不相关)


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

您需要的东西似乎不可能,因为任何限制都是针对单个参数而不是组合。 有一种在运行时而不是在编译时进行决策的解决方案

您需要:

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
您可以:

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

这不是很好,速度稍慢,但解决了问题。

您需要的东西似乎不可能实现,因为任何限制都是针对单个参数的,而不是组合参数。 有一种在运行时而不是在编译时进行决策的解决方案

您需要:

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
您可以:

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

它不是很好,速度慢了一点,但解决了问题。

在我的例子中,我的目标是禁止使用两个不同类型的参数,方法是将两个泛型标记为过时的
。我实际上找到了一种方法,通过使用一个扩展:

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

将列出所有泛型类型约束。这是C#文档,但VB支持相同的约束。如果没有列出您想要的内容,则无法使用泛型类型约束。所有泛型类型约束都会列出。这是C#文档,但VB支持相同的约束。如果您想要的没有列出,那么就不可能使用泛型类型约束。不幸的是,我需要通过使用有意义的消息标记带有两个泛型的
过时的
来禁止人们使用两种不同的类型。因此,我需要两种不同的方法,因此我可以用
标记带有两个泛型的方法。不过我找到了一种方法,很快就会与大家分享。不幸的是,我需要禁止人们使用两种不同的类型,在一种类型上标记两个泛型
过时
,并显示一条有意义的消息。因此,我需要两种不同的方法,因此我可以用
标记带有两个泛型的方法。不过我找到了一种方法,很快就会与大家分享。很好的解决方案,但你的问题可能会有所不同。@IvanH是和否。我想我应该提到我只想将一个
标记为过时的
,这表明我不能接受你的解决方案。但从技术上讲,我已经明确地询问了两种不同的方法。很抱歉造成混淆,我相信根据实际的用例,我们的两个答案都有很好的用处。如果两个通用方法必须实际执行某些操作,它将无法访问私有成员等,您的答案符合需要。解决方案很好,但您的问题可能应该有所不同。@IvanH是和否。我想我应该提到我只想标记一个
过时的
,这表明我不能使用您的解决方案。但从技术上讲,我已经明确地询问了两种不同的方法。很抱歉造成混淆,我相信根据实际的用例,我们的两个答案都有很好的用处。如果两个通用方法必须实际执行某些操作,那么它将无法访问私有成员等,并且您的答案符合需要。