История вопроса:
Вложенные процедуры (local functions) в Visual Basic появились только в версиях VB.NET начиная с VB 15.0 (Visual Studio 2017), что отличает их от классического VB6, где такой возможности не было. Эта особенность позволяет объявлять процедуры внутри других процедур, расширяя выразительность языка и упрощая организацию вспомогательной логики в одной области видимости.
Проблема
Частые ситуации, когда некоторая вспомогательная логика нужна только внутри конкретного метода и не требуется нигде больше. Раньше приходилось создавать частные методы класса, увеличивая засорение пространства имён и затрудняя навигацию по коду. Но и с local functions легко столкнуться с проблемами области видимости, ошибками доступа к переменным и трудностями отладки.
Решение
Вложенные процедуры позволяют инкапсулировать служебную логику в «родительской» процедуре, делая код более читаемым и ограничивая область видимости вспомогательных методов. В VB.NET объявление вложенных функций выглядит так:
Sub MainProc() Dim x As Integer = 5 Dim y As Integer = 10 Console.WriteLine($"Сумма — {Add(x, y)}") Function Add(a As Integer, b As Integer) As Integer Return a + b End Function End Sub
Ключевые особенности:
Могут ли вложенные процедуры иметь модификаторы доступа Public, Friend или Protected?
Нет, для вложенных процедур разрешён только уровень доступности внутри их "родительской" процедуры. Они не могут объявляться как Public/Friend/Protected и доступны только локально.
Можно ли объявить вложенную процедуру внутри конструкции For или If?
Нет, локальные функции допускается объявлять только на первом уровне внутри метода (процедуры), но не внутри вложенных блоков (например, For, If, While).
Могут ли вложенные процедуры быть асинхронными (Async Sub/Function)?
Да, можно объявлять async local functions, что позволяет инкапсулировать логику асинхронного выполнения внутри метода:
Async Sub DoOperationsAsync() Await LocalAsync() Async Function LocalAsync() As Task Await Task.Delay(1000) Console.WriteLine("Async operation completed.") End Function End Sub
В проекте был избыточно использован private методы вместо local functions, из-за чего десятки служебных процедур "замусорили" интерфейс класса. Навигация сильно усложнилась.
Плюсы:
Минусы:
Для внутренней логики был использован подход с локальными функциями: вся служебная обработка размещена внутри главного метода, код само-документируемый, легко сопровождать.
Плюсы:
Минусы: