sábado, 23 de marzo de 2013

Simulando operaciones de conjuntos con C#.

Es comun encontrarnos con problemas que involucran conjuntos de elementos los cuales hay manejar como tales, o sea garantizando que no contengan elementos repetidos y que esten definidas las operaciones de union, interseccion y diferencia.
Aqui dejo un ejemplo de una clase que he nombrado ObjectSet que implementa estos servicios sobrecrgando los operadores +, - y * para realizar las operaciones de unión, diferencia e intersección respectivamente.

La clase tiene un miembro privado una lista genérica.
private List<T> items;

A continuación se implementan los siguientes servicios que se esperan por parte los clientes para poder manipular los elementos contenidos en el conjunto.

AddItem
RemoveItem
RemoveAt
Count
Y una enumeración para obtener/establecer el valor de elementos dentro de la lista items.
Todo ello se encuentra en la seccion Wrappers de código.


Podrían seguirse declarando o incluso utilizar un acercamiento diferente haciendo que la clase sea un descendiente de List<>, preferí hacerlo así para poder controlar a que servicios de la clase los clientes tienen acceso y a cuales no de forma más simple.

Más adelante se sobreescriben algunos métodos para personalizar el comportamiento de la clase como por ejemlo a la hora de mostrala por pantalla [ToString], comparar entre sí objetos de la clase. Esto se encuentra en la seccion Overridings.

A continuación aparecen los constructores de la clase. Son tres y puede extenderse la clase creando otros.
  1. El constructor sin parámetros solo inicializa la lista.
  2. El constructor que toma como paramétro otro objecto copia los elementos del objeto hacia el nuevo
  3. El constructos que toma como parámetro un arreglo nos sirve inicializar un objeto de la clase partiendo del arreglo.

Y ahora, la próxima sección del código de implementación de la clase define como se comportarán los operadores: +, - y * para obtener el resultado de la operación Unión, Diferencia e Intersección respectivamente. Es aquí que se realiza el trabajo.
 
Por último un ejemplo sencillo de tres arreglos de cadenas y obtener el conjunto unión de los tres.
El código que usa esta clase pues es muy simple:
  

Conviene decir que esta clase no está completamente desarrollada ni he probado exahustivamente su código. Muchas mejoras se podrían hacer, por ejemplo se podria habilitar un método que devuelva los elementos del conjunto como un arreglo; pero creo que para ilustrar el propósito del post es suficiente.

Esta debería ser la filosofía para este tipo de problemas.