Почему ключевое слово "Call" требуется для методов классов, которые принимают параметры? - PullRequest
0 голосов
/ 25 января 2019

В моем классе несколько методов. Некоторые методы принимают параметры. Этим методам требуется ключевое слово «Call» для работы. Почему?

MyObject.MyMethod   'Works just fine without Call.

Call MyObject.MyMethod(arg1, arg2)  'Requires Call. Won't compile without it.

Ответы [ 2 ]

0 голосов
/ 25 января 2019

@ Ответ МатьеГиндона очень хорошо описывает часть, поэтому я решил заняться частью «почему».

Синтаксис VB перегружает скобки как синтаксический элемент. В случае вызова процедуры они используются для окружения списка аргументов :

 argument-list = [positional-or-named-argument-list] 
 positional-or-named-argument-list = *(positional-argument ",") required-positional-argument 
 positional-or-named-argument-list =/   *(positional-argument ",") named-argument-list 
 named-argument-list = named-argument *("," named-argument)

Обратите внимание, что определение для Список аргументов (5.6.13.1) подпадает под категорию Индексные выражения ( 5.6.13 ), и это не ' Это просто неправильное выражение, потому что парсер должен статически определять что индексируется . Это осложняется тем фактом, что () также используется для индексации массивов и индексирования индексированных элементов.

Сам оператор Call ( 5.4.2.1 ) использует список аргументов, но тот факт, что скобки могут также использоваться в качестве индексатора для переменной (массивов и т. Д.), Означает, что вероятность того, что выражение справа от Call может быть неоднозначным без следующего правила:

  • Если указано ключевое слово Call :
    • Если ссылочное выражение элемента является , указанный список аргументов является списком аргументов этого выражения.
    • В противном случае указанный список аргументов является пустым списком аргументов.

Принудительное использование скобок устраняет эту двусмысленность. Одним из примеров будет что-то вроде этого:

Sub Foo()
    Dim Bar As Object
    Call Bar 1  '<-- What is Bar here? Is this the default member of the object, or the Sub?
    Bar 1  '<-- This in unambiguous, because ( ) are required to use a default member indexer.
End Sub

Sub Bar(paramater As Integer)
    'Do something
End Sub
0 голосов
/ 25 января 2019

Call никогда не требуется.На самом деле он устарел с момента появления неявного синтаксиса вызовов в ... Visual Basic 4.0, если я правильно помню.

object.MemberName arg1, arg2

Обратите внимание, скобки пропали.Это было бы незаконно, как вы заметили:

object.MemberName (arg1, arg2)

Обратите внимание на пробел между MemberName и отверстием (: VBE всегда будет ставить пробел там.Вот что говорит VBE: «Хорошо, я возьму то, что в этих скобках, оценим это как выражение и передам результат по значению (независимо от того, подпись члена указывает ByRef, явно или нет)член, которого вы вызываете ".За исключением того, что (foo, bar) не является допустимым выражением, поэтому код не компилируется.

Когда MemberName возвращает значение, которое необходимо захватить вызывающей стороне, скобки ведут себя по-разному:

foo = object.MemberName(arg1, arg2)

Обратите внимание, что больше нет пробелов;VBE удалит его, если вы добавите какой-либо.

Итак, с более знакомым и конкретным примером - обратите внимание, что он не имеет ничего общего с объектами и членами:

MsgBox "Yes?", vbYesNo ' works fine
Call MsgBox("Yes?", vbYesNo) ' works fine
Call VBA.Interaction.MsgBox("Yes?", vbYesNo) ' works fine
MsgBox ("Yes?", vbYesNo) ' illegal
result = VBA.Interaction.MsgBox("Yes?", vbYesNo) ' works fine

CallКлючевое слово существует только в VBA6 / VBA7 для целей обратной совместимости, как и многие, многие другие языковые конструкции (на ум приходит While...Wend).Вот почему Rubberduck (отказ от ответственности: я один из администраторов этого проекта с открытым исходным кодом) помечает его использование как "устаревшее" и предоставляет инструменты для его удаления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...