Utilizando las expresiones lambda para facilitar algunos trabajos molestos
Más de una vez nos encontramos con la necesidad de ordenar una lista tipada (o sea una lista generica) y es necesario implementar IComparer<T>, no es que sea para mucho, es sólo un método como vemos en su definición
using System; namespace System.Collections.Generic { public interface IComparer<T> { int Compare(T x, T y); } }
pero más de una vez no tenemos ganas de crear una clase para esto o implementarla en una existente, bueno, para evitar hacer esto podemos utilizar un delegado y valernos de la inferencia de tipos de C# del siguiente modo
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication10 { class Program { static void Main(string[] args) { new Program().Prueba(); Console.ReadLine(); } private void Prueba() { List<Persona> personas = new List<Persona>() { new Persona() { Nombre = "Hernán", Apellido = "Crespo" }, new Persona() { Nombre = "Leonardo", Apellido = "Micheloni" }, new Persona() { Nombre = "Enzo", Apellido = "Francescoli" }, new Persona() { Nombre = "Ariel", Apellido = "Ortega" } }; personas.Sort(delegate(Persona x, Persona y) { return x.Apellido.CompareTo(y.Apellido); }); personas.ForEach(Console.WriteLine); } } public class Persona { private string _nombre; public string Nombre { get { return _nombre; } set { _nombre = value; } } private string _apellido; public string Apellido { get { return _apellido; } set { _apellido = value; } } public override string ToString() { return string.Format("{0} {1}", this.Apellido, this.Nombre); } } }
Y esto funciona muy bien, simplemente creamos un delegado que represente al método Compare<Persona> y la inferencia de tipos hacer el resto, lee el método anónimo se fija los parámetros, el valor de retorno, en cuál de las sobrecargas del método Sort encaja y listo, mágico y muy bonito, pero vamos a ir un paso más allá.
Facilitando la creación de métodos anónimos con expresiones Lambda
Por definición las expresiones Lambda son funciones anónimas que pueden contener expresiones o declaraciones y pueden ser utilizadas para crear delegados o árboles de expresión, entonces podemos reemplazar el delegado con una bonita expresión Lambda, sí, de este modo:
private void Prueba() { List<Persona> personas = new List<Persona>() { new Persona() { Nombre = "Hernán", Apellido = "Crespo" }, new Persona() { Nombre = "Leonardo", Apellido = "Micheloni" }, new Persona() { Nombre = "Enzo", Apellido = "Francescoli" }, new Persona() { Nombre = "Ariel", Apellido = "Ortega" } }; personas.Sort((x, y) => x.Apellido.CompareTo(y.Apellido)); personas.ForEach(Console.WriteLine); }
Hermoso, con una linda línea podemos ordenar el listado de ídolos de River Plate (en el cual me incluyu :-P ) y si descompilamos con Reflector vemos lo que pasó
internal class Program { // Methods private static void Main(string[] args) { new Program().Prueba(); Console.ReadLine(); } private void Prueba() { List<Persona> <>g__initLocal0 = new List<Persona>(); Persona <>g__initLocal1 = new Persona(); <>g__initLocal1.Nombre = "Hern\x00e1n"; <>g__initLocal1.Apellido = "Crespo"; <>g__initLocal0.Add(<>g__initLocal1); Persona <>g__initLocal2 = new Persona(); <>g__initLocal2.Nombre = "Leonardo"; <>g__initLocal2.Apellido = "Micheloni"; <>g__initLocal0.Add(<>g__initLocal2); Persona <>g__initLocal3 = new Persona(); <>g__initLocal3.Nombre = "Enzo"; <>g__initLocal3.Apellido = "Francescoli"; <>g__initLocal0.Add(<>g__initLocal3); Persona <>g__initLocal4 = new Persona(); <>g__initLocal4.Nombre = "Ariel"; <>g__initLocal4.Apellido = "Ortega"; <>g__initLocal0.Add(<>g__initLocal4); List<Persona> personas = <>g__initLocal0; personas.Sort(delegate (Persona x, Persona y) { return x.Apellido.CompareTo(y.Apellido); }); personas.ForEach(new Action<Persona>(Console.WriteLine)); } }
En las líneas remarcadas vemos que efectivamente el compilador creó el mismo delegado que habíamos definido en el primer ejemplo, sólo que nuestro código quedó mucho mas bonito y compacto gracias a las expresiones Lambda.
Hasta la próxima.
No hay comentarios:
Publicar un comentario