Historia de la cuestión:
Los procedimientos anidados (funciones locales) en Visual Basic aparecieron solo en las versiones de VB.NET comenzando desde VB 15.0 (Visual Studio 2017), lo que los diferencia del clásico VB6, donde no había tal posibilidad. Esta característica permite declarar procedimientos dentro de otros procedimientos, ampliando la expresividad del lenguaje y simplificando la organización de la lógica auxiliar en un ámbito único.
Problema
Situaciones frecuentes en las que una cierta lógica auxiliar solo es necesaria dentro de un método específico y no se requiere en ningún otro lugar. Anteriormente, era necesario crear métodos privados de clase, aumentando la saturación del espacio de nombres y dificultando la navegación por el código. Pero también con las funciones locales pueden surgir problemas de alcance, errores de acceso a variables y dificultades para depurar.
Solución
Los procedimientos anidados permiten encapsular la lógica auxiliar dentro del procedimiento "padre", haciendo que el código sea más legible y limitando el alcance de los métodos auxiliares. En VB.NET, la declaración de funciones anidadas se ve así:
Sub MainProc() Dim x As Integer = 5 Dim y As Integer = 10 Console.WriteLine($"Suma — {Add(x, y)}") Function Add(a As Integer, b As Integer) As Integer Return a + b End Function End Sub
Características clave:
¿Pueden los procedimientos anidados tener modificadores de acceso Public, Friend o Protected?
No, para los procedimientos anidados solo se permite el nivel de accesibilidad dentro de su propio procedimiento "padre". No pueden declararse como Public/Friend/Protected y son accesibles solo localmente.
¿Se puede declarar un procedimiento anidado dentro de una construcción For o If?
No, las funciones locales se pueden declarar solo en el primer nivel dentro del método (procedimiento), pero no dentro de bloques anidados (por ejemplo, For, If, While).
¿Pueden los procedimientos anidados ser asíncronos (Async Sub/Function)?
Sí, se pueden declarar funciones locales asíncronas, lo que permite encapsular la lógica de ejecución asíncrona dentro del método:
Async Sub DoOperationsAsync() Await LocalAsync() Async Function LocalAsync() As Task Await Task.Delay(1000) Console.WriteLine("Operación asíncrona completada.") End Function End Sub
En el proyecto se usaron de forma excesiva métodos privados en lugar de funciones locales, lo que "ensució" la interfaz de la clase con decenas de procedimientos auxiliares. La navegación se complicó mucho.
Ventajas:
Desventajas:
Para la lógica interna, se utilizó un enfoque con funciones locales: todo el procesamiento auxiliar se colocó dentro del método principal, el código es auto-documentado y fácil de mantener.
Ventajas:
Desventajas: