Я склонен ненавидеть повторения в коде, поэтому, когда я сталкиваюсь с проблемой, где единственными отличиями являются типы, я склонен использовать обобщенные типы. Исходя из 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 против 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)
, но ограничения должны быть классами Inheritable, поэтому нельзя использовать ни 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