【发布时间】:2012-01-26 19:18:41
【问题描述】:
我倾向于讨厌代码中的重复,所以当我遇到唯一不同的是类型的问题时,我倾向于使用泛型。来自 C++ 背景,我发现 vb.net 的版本相当令人沮丧,我知道 C++ 有模板专业化,我猜 vb.net 没有 所以我所拥有的是一组例程,它们执行完全相同的代码,而不管传递的类型如何。
类似的东西
Public Sub decision(Of T)(ByVal a As T, ByVal b As Integer)
If b > 10 then
gt(a)
Else
lt(a)
End If
End Sub
我只将两种类型传递给例程,字符串和整数,这些例程对字符串的处理与对整数的处理不同。
Public Sub gt(ByVal a As String)
Public Sub gt(ByVal a As Integer)
Public Sub lt(ByVal a As String)
Public Sub lt(ByVal a As Integer)
这是我对 vb.net vs C++ 感到沮丧的地方,AFAIK,C++ 会在编译时检查类型,并且只针对发送到决策的类型。但是,在 vb.net 中,我收到 T 类型无法转换为字符串或整数的错误
Error 3 Overload resolution failed because no accessible 'gt' can be called with these arguments:
'Public Sub gt(a As String)': Value of type 'T' cannot be converted to 'String'.
'Public Sub gt(a As Integer)': Value of type 'T' cannot be converted to 'Integer'.
我尝试了约束Public Sub decision(Of T As {String, Integer})(ByVal a As T, ByVal b As Integer),但约束必须是可继承的类,因此既不能使用String,也不能使用Integer。
我的下一个解决方案是添加gt 和lt 的通用版本:
Public Sub lt(Of T)(ByVal a As T)
Debug.Fail("Not Implemented")
End Sub
Public Sub lt(Of T)(ByVal a As T)
Debug.Fail("Not Implemented")
End Sub
嘿!没有更多的编译错误,但是唯一被调用的例程是gt 和lt 的通用版本。鉴于前面的无法转换错误,我认为这是有道理的。我之前在泛型例程的非泛型重载时遇到过这个问题,当时我找不到解决方案,现在也找不到解决方案。
有什么我遗漏的东西可以使这种类型的重载成为可能吗?
编辑:一个完整的工作示例
Module Module1
Sub Main()
decision(1, 5)
decision(1, 10)
decision("hello world", 5)
decision("hello world", 10)
End Sub
Public Sub decision(Of T)(ByVal a As T, ByVal b As Integer)
If b > 10 Then
gt(a)
Else
lt(a)
End If
End Sub
Public Sub gt(ByVal a As String)
Debug.WriteLine(" gt string: " + a)
End Sub
Public Sub gt(ByVal a As Integer)
Debug.WriteLine(" gt integer: " + a.ToString)
End Sub
Public Sub lt(ByVal a As String)
Debug.WriteLine(" lt string: " + a)
End Sub
Public Sub lt(ByVal a As Integer)
Debug.WriteLine(" lt integer: " + a.ToString)
End Sub
#If False Then
Public Sub gt(Of T)(ByVal a As T)
Debug.Fail("Not implemented")
End Sub
Public Sub lt(Of T)(ByVal a As T)
Debug.Fail("Not implemented")
End Sub
#End If
End Module
【问题讨论】:
-
问题不在于你对
decision的声明,而是调用方法或类——请告诉我们。您的情况不需要泛型,您最初显示的重载很好。 -
添加了一个演示问题的工作示例,附加代码将出现无法转换错误,将
#if False Then更改为#If True Then将始终调用通用版本。 -
是的,我明白,但这也不是问题所在。你能做一些真实的例子吗?
-
不幸的是没有。我不喜欢发布公司代码,即使我知道它不会造成任何伤害,我只是不想冒险。我想我不确定还需要什么,因为上面的代码与我在其他地方遇到的问题相同,也许如果你让我知道你在寻找什么,我可以提供更多信息。从那以后,我想出了另一种解决问题的方法,但是由于我两次遇到这个问题,我现在对提供的示例更感兴趣,所以我知道将来如何解决这个问题。我有上面代码的 C++ 版本,可以正常工作。
-
嗯......这种情况永远不需要。如果你有另一个修复,那很好。但是没有实际的方法和调用方法我就忍不住了。
标签: vb.net generics overloading specialization