95 - Expresiones lambda : Acceso a las variables externas a la expresión lambda


Hemos visto en conceptos anteriores que una expresión lambda es cuando enviamos a un método una función anónima.

Dentro de la función lambda podemos acceder a los parámetros de la misma si los tiene, definir variables locales y veremos ahora que podemos acceder a variables externas a la expresión lambda definida.

Problema

Confeccionar una clase que administre un vector con 5 elementos enteros.
Definir un método que recorra el vector y llame a una expresión lambda que pueda analizar cada elemento del vector.

Llamar al método que recorre el vector y resolver mediante lambdas los siguientes algoritmos:

  • La cantidad de múltiplos de 3
  • La suma de todas las componentes superiores a 50

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lambda4
{
    public delegate void Retorna(int elemento);

    public class Vector
    {
        private int[] vec = { 10, 23, 200, 12, 75 };

        public void Imprimir()
        {
            Console.WriteLine("Listado completo del vector.");
            foreach (var elemento in vec)
                Console.Write("{0}-", elemento);
            Console.WriteLine();
        }

        public void Recorrer(Retorna retorna)
        {
            foreach (var elemento in vec)
                retorna(elemento);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Vector v = new Vector();
            v.Imprimir();
            var multiplos3 = 0;
            v.Recorrer(elemento => {
                if (elemento % 3 == 0)
                    multiplos3++;
            });
            Console.WriteLine("Cantidad de elementos múltiplos de 3: {0}", multiplos3);
            var suma = 0;
            v.Recorrer(elemento => {
                if (elemento > 50)
                    suma += elemento;
            });
            Console.WriteLine("La suma de todas las componentes superiores a 50: {0}", suma);
            Console.ReadKey();
        }
    }
}

Definimos un delegado que recibe un entero y no retorna nada:

    public delegate void Retorna(int elemento);

Declaramos una clase llamada Vector que define un arreglo de enteros y almacena 5 valores:

    public class Vector
    {
        private int[] vec = { 10, 23, 200, 12, 75 };

Imprimimos el arreglo en forma completa:

        public void Imprimir()
        {
            Console.WriteLine("Listado completo del vector.");
            foreach (var elemento in vec)
                Console.Write("{0}-", elemento);
            Console.WriteLine();
        }

El método Recorrer recibe un delegado y mediante el mismo llama a la expresión lambda pasando en cada llamada un elemento del arreglo:

        public void Recorrer(Retorna retorna)
        {
            foreach (var elemento in vec)
                retorna(elemento);
        }

En la función Main creamos un objeto de la clase Vector:

        static void Main(string[] args)
        {
            Vector v = new Vector();
            v.Imprimir();

Lo nuevo aparece cuando llamamos al método Recorrer y dentro de la expresión lambda tenemos acceso al contador multplos3:

            var multiplos3 = 0;
            v.Recorrer(elemento => {
                if (elemento % 3 == 0)
                    multiplos3++;
            });
            Console.WriteLine("Cantidad de elementos múltiplos de 3: {0}", multiplos3);

Para sumar los elementos mayores a 50 fuera de la expresión lambda definimos e iniciamos un acumulador llamado "suma" y luego lo modificamos dentro de la expresión lambda:

            var suma = 0;
            v.Recorrer(elemento => {
                if (elemento > 50)
                    suma += elemento;
            });
            Console.WriteLine("La suma de todas las componentes superiores a 50: {0}", suma);

Retornar