3

Я нашел некоторое интересное поведение с тем, как VB.NET обрабатывает сигнатуры функций. Это новое поведение началось в VS2012 и продолжает сохраняться в VS2013.Новое поведение подписи функции VB.NET в Visual Studio 2012/2013

Рассмотрим следующий фрагмент кода:

Class test 
    Function a(x As String, Optional y As Boolean = False) As String 
     Return "function a() was called" 
    End Function 

    Function a(x As String) As String 
     Return "second function a() was called" 
    End Function 
End Class 

Моя первая мысль, что это не будет компилироваться, что верно в VS2010 и более ранних версиях. Однако VS2012 и VS2013 компилируют код без предупреждения. Если вы затем выполните следующее:

Dim x As New test() 
MsgBox(x.a("123")) 

Сообщение указывает, что вызывается функция без необязательного параметра.

Есть ли способ отключить это поведение? Казалось бы, это может открыть дверь разработчику, неосознанно добавляя функции с тем же именем, что и другие функции, которые имеют необязательные параметры, вызывая нежелательные переадресации.

+0

Вы должны действительно отказаться от использования функции 'MsgBox', которая существует только по соображениям совместимости при переносе из старого Код VB6. 'System.Windows.Forms.MessageBox.Show (...)' - путь. –

+3

Как сказал Дэвид Р в своем ответе, у C# такое же поведение. Поэтому, если это изменение устраняет различия между VB.NET и C#, я считаю это хорошим изменением. –

+2

Аргумент просто не является дополнительным, когда вы предоставляете перегрузку. Напишите здравый код, и все части встанут на свои места. –

ответ

2

Я прочитал руководство компании Microsoft на Overload Resolution (Visual Basic) для Visual Studio 2013 и шаг 5 говорится, что:

The compiler considers the remaining overloads in pairs. For each pair, it compares the data types of the defined parameters. If the types in one of the overloads all widen to the corresponding types in the other, the compiler eliminates the latter. That is, it retains the overload that requires the least amount of widening.

Он явно не указанных в этой статье, но не расширение не требуется, чтобы выбрать функцию с не факультативный параметры. Компилятор сохраняет вторую подпись, потому что она не требует расширения. Я не могу определить, почему это изменилось между VS2010 и VS2012.

Такое поведение является явно указано в аналогичном CSharp Guide:

If two candidates are judged to be equally good, preference goes to a candidate that does not have optional parameters for which arguments were omitted in the call. This is a consequence of a general preference in overload resolution for candidates that have fewer parameters.

0

Ммм, я нашел этот пост после того, как встретив последующих, то, что мне кажется, аномалия:

Class SealedClass 
    Public Sub Test(Param1 As String) 
     'Some code 
    End Sub 
    Public Sub Test(Param1 As String, Optional Param2 As String = "") 
     'Some other code 
    End Sub 
End Class 

MustInherit Class BaseClass 
    MustOverride Sub Test(ByVal Param1 As String) 
    MustOverride Sub Test(ByVal Param1 As String, Optional ByVal Param2 As String = "") 
End Class 

Class SubClass 
    Inherits BaseClass 
    Public Overrides Sub Test(Param1 As String) 
     'Some code 
    End Sub 
    Public Overrides Sub Test(Param1 As String, Optional Param2 As String = "") 
     'Some other code 
    End Sub 
End Class 

В приведенном выше коде SealedClass компилируется просто отлично, в соответствии с приведенным выше комментарием.

Однако, хотя BaseClass компилируется, SubClass bleets, что Sub Test в BaseClass с дополнительным параметром должны быть переопределены.

Для меня это непоследовательно. Кто-нибудь имеет какой-либо вклад? Очевидно, что приведенный выше код является просто иллюстрацией; мой собственный код пытается обеспечить перегрузки для создания базы данных такими параметрами, как номер порта, аутентификация и т. д.

Смежные вопросы