History of the Issue:
Nested procedures (local functions) in Visual Basic were introduced only in VB.NET versions starting from VB 15.0 (Visual Studio 2017), which differentiates them from classic VB6, where such capability did not exist. This feature allows procedures to be declared within other procedures, enhancing the expressiveness of the language and simplifying the organization of helper logic within a single scope.
The Problem
There are frequent situations where some helper logic is only needed within a specific method and is not required elsewhere. Previously, it was necessary to create private class methods, cluttering the namespace and complicating navigation through the code. However, local functions can also encounter visibility issues, variable access errors, and debugging difficulties.
The Solution
Nested procedures allow encapsulating service logic in the "parent" procedure, making the code more readable and limiting the visibility of helper methods. In VB.NET, the declaration of nested functions looks like this:
Sub MainProc() Dim x As Integer = 5 Dim y As Integer = 10 Console.WriteLine($"Sum — {Add(x, y)}") Function Add(a As Integer, b As Integer) As Integer Return a + b End Function End Sub
Key Features:
Can nested procedures have access modifiers Public, Friend, or Protected?
No, for nested procedures, only the level of accessibility within their "parent" procedure is allowed. They cannot be declared as Public/Friend/Protected and are only available locally.
Is it possible to declare a nested procedure within a For or If construct?
No, local functions can only be declared at the top level within the method (procedure), but not inside nested blocks (e.g., For, If, While).
Can nested procedures be asynchronous (Async Sub/Function)?
Yes, you can declare async local functions, which allows encapsulating asynchronous execution logic within the method:
Async Sub DoOperationsAsync() Await LocalAsync() Async Function LocalAsync() As Task Await Task.Delay(1000) Console.WriteLine("Async operation completed.") End Function End Sub
In the project, private methods were excessively used instead of local functions, which led to dozens of service procedures "cluttering" the class interface. Navigation became significantly more complicated.
Pros:
Cons:
For internal logic, a local functions approach was used: all service processing was placed inside the main method, the code is self-documenting, and easy to maintain.
Pros:
Cons: