Clases consultables desde Linq
No se vosotros, pero a mí me da especial pereza cuando tengo que crear métodos para buscar determinados valores dentro de una colección de objetos, ya sé que los métodos de búsqueda vienen a ser siempre los mismos y la implementación no varía mucho de una vez a otra, pero cuando has de obtener ya valores calculados o rangos de valores o combinaciones más perversas la cosa cambia. Para facilitarnos este trabajo tenemos linq y ahora explicaremos cómo construir nuestras clases para que puedan ser consultadas mediante linq.
Nota: Este articulo lo redacte ya hace un tiempo para documentar un posible uso en el trabajo.
La clase base
Antes de nada debemos construir la clase que contendrá la información que almacenamos, para esta demos optaremos por la original clase persona, con los atributos nombre, apellidos, edad, dni y sexo.
| class Persona { string _nombre; string _apellidos; int _edad; string _dni; int _sexo; public string nombre { |
Colección de objetos
Ahora pasamos a la chicha, hemos de diseñar una clase que contenga la colección de objetos sobre los cuales queremos consultar. Para que linq pueda realizar consultas esta colección debe implementar el interface IEnumerable, este interface expone el IEnumerator interno que permite una iteración simple a través de los objetos que contiene la colección. Como se puede ver, también debemos implementar el interface IEnumerator dentro de la colección. Es importante ver que el IEnumerator se define dentro de la clase colección no fuera, ya que ha de poder acceder a la colección de objetos, en nuestro caso conjuntoPersonas.
También hay que destacar que debemos implementar el interface con establecimiento inflexible de tipos, es decir que definimos que tipo de objeto contiene, <Persona>, si no se hiciera así Linq no sabría que propiedades tiene el objeto y no podría realizar las consultas. Además esta forma nos da una mayor seguridad de tipos y es más eficiente que las colecciones que nosotros creemos con establecimiento inflexible de tipos.
Veamos la clase y su implementación.
| class Personal : IEnumerable<Persona> { private Persona[] conjuntoPersonas; public void add(Persona nuevaPersona) { int l; if (conjuntoPersonas == null) { conjuntoPersonas = new Persona[1]; conjuntoPersonas[0] = nuevaPersona; l = 1; } else { l = conjuntoPersonas.Length; Persona[] _arr = new Persona[l+1]; conjuntoPersonas.CopyTo(_arr, 0); _arr[l] = nuevaPersona; conjuntoPersonas = _arr; } } public IEnumerator<Persona> GetEnumerator() { return new PersonaEnumerator(conjuntoPersonas); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return new PersonaEnumerator(conjuntoPersonas); } private class PersonaEnumerator : IEnumerator<Persona> |
Hay que fijarse que la funcion GetEnumerator del interface IEnumerable y la propiedad Current del IEnumerator están sobre cargadas, esto se debe a que para cumplir con el interface hace falta que estén implementadas para objetos genéricos y para el objeto específico, además en mis pruebas, cuando implementaba las funciones con objetos genéricos tenía que indicar toda la ruta hasta la función del interface para que no me diera error.
GetEnumerator
| public IEnumerator<Persona> GetEnumerator() (objeto específico) |
| System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() (objeto genérico) |
Current
| Object System.Collections.IEnumerator.Current (objeto genérico) |
| public Persona Current (objeto específico) |
Con esto ya tenemos nuestra clase conultable en Linq y podremos hacer consultas como por ejemplo, las persona con mas de 30 años:
| var c = from ps in p where ps.edad > 30 select ps; |
O la media de edad de cada sexo:
|
var res = from ps in p group ps by ps.sexo into ps2 select new {sexo = ps2.Key, avg = ps2.Average(c => c.edad)}; |
Comentarios
La potencia del Linq la veremos sobre todo cuando dispongamos de diversas clases y hagamos joins entre ellas, simplificando mucho el proceso de cruzar las referencias.
Hemos de tener en cuenta que, para tareas sencillas, Linq no es optimo. Recorrer un array buscando un valor concreto, por ejemplo, es altamente optimizado por el compilador dando como resultado un procesos hasta 40 veces más rápido.
descarga proyecto de ejemploP.D: No soy la persona que mejor se explica del mundo así que si algo no esta bien explicado o hace falta que le de otra vuelta decírmelo.

Buy:Arimidex.Lumigan.Retin-A.Human Growth Hormone.Petcam (Metacam) Oral Suspension.Valtrex.Synthroid.Zyban.Actos.Prevacid.Mega Hoodia.100% Pure Okinawan Coral Calcium.Zovirax.Accutane.Prednisolone.Nexium….