¿Querés chatear en mi blog? Fijate abajo, en la columna derecha podés usar GTalk
(Si no te funciona con IE probá con Firefox)

lunes, 14 de enero de 2008

LINQ y otras yerbas de C# 3.0

En este post expongo con un ejemplo simple, la impresión de números pares del 1 al 20, algunas características nuevas de C# 3.0 como LINQ, Lamba expressions, Extensions methods, comparadas con algunas características que ya estaban incluidas en C# 2.0 como Anonymous Method en contraste con nuestro viejo y querido foreach. Es un ejemplo muy simplista, pero sirve para ilustrar las nuevas características incorporadas en la nueva versión de C#.

Código:

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

namespace LINQ_Lab_1
{
    class Program
    {
        static int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };

        static void Main(string[] args)
        {
            PrintHeadLine("For each sample - C# 1.0");
            PrintEvenNumbersForEach();

            PrintHeadLine("Anonymus Method - C# 2.0");
            PrintEvenNumbersAnonymusMethod();

            PrintHeadLine("Anonymus Method 2 - C# 2.0");
            PrintEvenNumbersAnonymousMethod2();

            PrintHeadLine("LINQ - C# 3.0");
            PrintEvenNumbersLinq();

            PrintHeadLine("Lambda Expressions - C# 3.0");
            PrintEvenNumbersLamba();

            PrintHeadLine("Extension Methods - C# 3.0");
            PrintEvenNumbersExtensionMethods();

            PrintHeadLine("Anonymous Type - C# 3.0");
            PrintEvenNumbersAnonymousType();

            Console.ReadLine();
        }

        static void PrintSeparator()
        {
            Console.WriteLine("---------------------------");
        }

        static void PrintHeadLine(string text)
        {
            PrintSeparator();
            Console.WriteLine(text);
            PrintSeparator();
        }

        /// <summary>
        /// Utilizando la clasica version con Foreach
        /// C# 1.0
        /// </summary>
        static void PrintEvenNumbersForEach()
        {
            /* Viejo y querido foreach
             * */
            foreach (int n in numbers)
                if (n % 2 == 0)
                    Console.WriteLine(n.ToString());
        }

        /// <summary>
        /// Utilizando delegados y metodos anonimos
        /// C# 2.0
        /// </summary>
        static void PrintEvenNumbersAnonymusMethod()
        {
            /* Aqui se esta utilizando un delegado que representa un metodo anonimo
             * con el codigo: "return n % 2 == 0"
             * */
            int[] evens = Array.FindAll(numbers, delegate(int n) { return n % 2 == 0; });
            foreach (int n in evens)
                Console.WriteLine(n.ToString());
        }

        /// <summary>
        /// Utilizando Anonymous Method 2
        /// C# 2.0
        /// </summary>
        static void PrintEvenNumbersAnonymousMethod2()
        {
            /* La version mas compacta: 1 sola linea

             * */
            Array.ForEach(numbers, delegate(int n) { if (n % 2 == 0) Console.WriteLine(n.ToString()); });
        }

        /// <summary>
        /// Utilizando LINQ
        /// C# 3.0
        /// </summary>
        static void PrintEvenNumbersLinq()
        {
            //Expresion LINQ al mejor estilo SQL
            var evens = from n in numbers
                        where n % 2 == 0
                        select n.ToString();

            foreach (string n in evens)
                Console.WriteLine(n);
        }

        /// <summary>
        /// Utilizando Lambda Expressions
        /// C# 3.0
        /// </summary>
        static void PrintEvenNumbersLamba()
        {
            /* Aqui se esta utilizando un expresion lambda
             * que se puede interpretar como "para todo n que cumpla con la regla n % 2 == 0"
             * podemos ver el codigo representa una expresion más natural:
             * "Buscar todos los n en numbers que cumplan con la condicion n % 2 == 0"
             * */

            var evens = Array.FindAll(numbers, n => n % 2 == 0);
            foreach (int n in evens)
                Console.WriteLine(n.ToString());

        }

        /// <summary>
        /// Utilizando Extension Methods
        /// C# 3.0
        /// </summary>
        static void PrintEvenNumbersExtensionMethods()
        {
            /* Aqui utilizamos Extension Methods y una expresion lambda para
             * el predicado
             * */

            var evens = numbers.Where(n => n % 2 == 0);
            foreach (int n in evens)
                Console.WriteLine(n.ToString());
        }

        /// <summary>
        /// Utilizando LINQ y Anonymous Types
        /// C# 3.0
        /// </summary>
        static void PrintEvenNumbersAnonymousType()
        {
            /* En la clausula "select" de la expresion LINQ creamos un tipo anonimo
             * conformado por el miebro "n" con el valor del entero y otro miembro
             * "name" que representa a n.ToString().
             * Luego utilizamos "n.name"
             * */
            var evens = from n in numbers
                        where n % 2 == 0
                        select new { n, name = n.ToString() };

            foreach (var n in evens)
                Console.WriteLine(n.name);
        }

    }
}

Resultado:

image

Performance:

Aquí podemos observar que en cuestiones de performance el método más veloz es el foreach, mientras que el que peor rendimiento posee es del de creación de un tipo anónimo.

image

 

GB.

No hay comentarios: