Una sinfonía en C#

Un pequeño aporte a la comunidad de habla hispana.

Novedades de C#7: Funciones locales

Ya hemos visto algunas de las novedaes de C#7 en este espacio y es momento de hablar de las funciones locales.

¿Qué son las funciones locales?

En pocas palabras C#7 nos da la posibilidad de declarar una función dentro de otra…si, dentro de otra, con las ventajas que esto aporta:

  • Visibilidad acotada
  • Acceso a las variables del entorno en que se declara
  • No ensuciamos el código con algo muy específico del contexto que necesitamos

Vamos a ver un ejemplo, imaginemos que tenemos una estructura tipo árbol guardada en una base de datos

image

Simple, cada elemento tiene un padre y así se arma el árbol, del lado de C# tenemos:

class Hoja
{
    public string Nombre { get; set; }
    public int Id { get; set; }
    public IList Hijos { get; set; }
    public Hoja Padre { get; set; }
}

Básicamente tiene el nombre, id, el id del padre y el listado de hijos, lo que queremos hacer es armar un árbol poniendo los hijos, lo natural sería hacer algo recursivo.

void BuscarHijos(Hoja hoja, IEnumerable hojas)
{
    foreach (var hijo in hojas.Where(i => i.Padre.Id == hoja.Id))
    {
        hoja.Hijos.Add(hijo);
        BuscarHijos(hijo, hojas);
    }
}

public IEnumerable Generar()
{
    var hojas = Hoja.GetAll();
    var lista = new List();

    foreach (var item in hojas.Where(i => i.Padre == null)) // buscamos los nodos raíz
    {
        lista.Add(item);
        BuscarHijos(item, hojas);
    }

    return lista;
}

Entonces, primero buscamos aquellas hojas que no tiene padres (son las raices) y después iteramos esa colección y buscamos las hojas que tienen como padre al nodo raíz actual, usamos una función recursiva para buscar hijos de hijos, esto debería funcionar.

Usando funciones locales.

El mismo código con funciones locales se pude hacer así:

var lista = new List();

foreach (var item in hojas.Where(i=>i.Padre == null))
{
    lista.Add(item);
    BuscarHijos(item);

    void BuscarHijos(Hoja hoja)
    {
        foreach (var hijo in hojas.Where(i => i.Padre.Id == hoja.Id))
        {
            hoja.Hijos.Add(hijo);
            BuscarHijos(hijo);
        }
    };
}

Como vemos declaramos la función BuscarHijos no solo dentro del método sino dentro del bucle y acotamos bien su impacto, además tenemos visibilidad de la lista de hojas y de la misma función BuscarHijo, super cool

Hay más detalles sobre las funciones locales en este link, y la propuesta original de la funcionalidad acá.

Nos leemos.

Loading