Я склонен ненавидеть повторения в коде, поэтому, когда я сталкиваюсь с проблемой, в которой различаются только типы, я склонен использовать дженерики. Исходя из фона 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 не может быть преобразован в String или Integer.
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
, а в вызывающем методе или классе - пожалуйста, покажите нам это. Ваша ситуация не требует дженериков, перегрузка, которую вы показали изначально, была в порядке. - person Ry-♦   schedule 26.01.2012#if False Then
на#If True Then
всегда будет вызывать общую версию. - person Apeiron   schedule 26.01.2012