Enlaces e información

Comenta lo que creas oportuno.


Otros posts
Sudoku
MonoRails o .NET on Rails

Guerra abierta al switch… case

Escrito por Roberto M. Oliva en Agosto 10th, 2006

Me estare volviendo paranoico… pero cada vez que veo un switch… case en un codigo C# (O Select… Case en Visual Basic.NET) me entra una especie de sarpullido que no puedo evitar.
Supongamos que tenemos una enumeracion y queremos presentar un texto dependiendo de esa enumeracion:

public enum eTipoMoneda
{
eDolar = 0,
ePeseta = 1,
eEuro = 2
}

public string DescripcionMoneda (eTipoMoneda tipo)
{
switch(tipo)
{
case eDolar:
return “Dolar”;
case ePeseta:
return “Peseta”;
case eEuro:
return “Euro”;
}
}

Algo muy simple, verdad… y bastante utilizado, por cierto. Bien, supongamos que montamos un software complejísimo en base a un sistema multimoneda con esta enumeracion de tipos y, no solo eso, sino que realizamos diferentes operaciones dependiendo de cada moneda: Implementariamos un select… case por cada operacion para diferenciarlas. Puede llegar un momento en el que el código sea totalmente insostenible.
Hay una regla básica, si hay un sitio donde aparecen un select con varios cases, es hora de implementar un interface. Como se haría? Utilizando el ejemplo anterior:

public interface ITipoMoneda
{
string Nombre{get;}
eTipoMoneda TipoMoneda {get;}
}

Podriamos implementar una clase para cada tipo de la siguiente manera:

public class CDolar, ITipoMoneda
{
public Nombre
{
get{ return “Dolar”;}
}
public eTipoMoneda
{
get { return eTipoMoneda.eDolar; }
}
}

public class CPeseta, ITipoMoneda
{
public Nombre
{
get{ return “Peseta”;}
}
public eTipoMoneda
{
get { return eTipoMoneda.ePeseta; }
}
}

Y tambien con el euro. He implementado la propiedad eTipoMoneda, para mantener un nexo de union con respecto al primer ejemplo, aunque en C# seria equivalente a: typeof() o GetType() en Visual Basic.NET.
Podriamos crear un contenedor estático que devuelva una lista con los tipos de monedas:

IList<ITipoMoneda> objLista = new List<ITipoMoneda>();
objLista.Add(new CDolar);
objLista.Add(new CPeseta);

Ahora si queremos mostrar las monedas de las que da soporte nuestro programa:

foreach(ITipoMoneda moneda in objLista)
Consele.WriteLine ( moneda.Nombre );

Seria fácil dar soporte a una nueva moneda en el programa…. verdad??

Tambien podríamos implementar fácilmente funcionalidad específica:

public interface ITipoMoneda
{
string Nombre{get;}
eTipoMoneda TipoMoneda {get;}
double FactorConversion {get;}
}

Entonces, una conversion entre monedas sería algo así:

public decimal ConvertirMonedas (ITipoMoneda objMonedaInicial, ITipoMoneda objMonedaFinal, decimal cantidad)
{
return (cantidad * objMonedaInicial.FactorConversion) / objMonedaFinal.FactorConversion;
}

Pensad en la cantidad de switch… cases que nos hemos comido con esta implementación. Pensad en lo fácil que es implementar nuevas monedas y, fijaros que esta última función siempre funcionará aún añadiendo nuevas monedas al sistema. Para dotar a estas clases de funcionalidad más específica vienen en nuestra ayuda los delegados, potenciados en .NET 2.0 con los objetos Action y Predicate…. bueno, ya hablaré más de ellos en otro post.
Por todo esto cuando veo un switch…case siempre pienso que seguramente haya una mejor manera de implementar el código… y, efectivamente, siempre la hay.



Escriba un comentario

Dediquele un momento a comentar lo que piensa. Esta permitido usar HTML básico para formatear el escrito.

Comentarios de los lectores

[…] Esto viene de un post que puse hace unos dias confesando mi odio a los multiples switch. […]

[…] Guerra abierta al switch-case Preparación de un interfaz para testeo unitario Testeando el interfaz Mockeando el interfaz SourceForge y la idiosincrasia de la gente […]

Pues a mi, en la uni, me han comentado que antes de usar if anidadoes es mucho mejor usar switch-case, aunque estoy de acuerdo contigo, que son bastantes problematicos cuando el codigo empieza a ser complejo

Sí, si por supuesto.
Los if’s anidados son, a la larga, un problema en el codigo: daifícil lectura y seguimiento de la ejecución.
Pero, si en tu código, ves un switch… case, por lo menos planteate como hacer mediante polimorfismo. Es muy posible que no lo necesites, pero es muy seguro que te clarifique mucho el código, te lo haga más sólido y a la larga te sea mucho mñas facil de mantener.
Un saludo

Great site you’ve got! I bet you’re professionals!

i am going to tell my friends about this site - it’s just perfect!

No doubts it’s a good page!

Great site you’ve got! I bet you’re professionals!

Ringraziamenti molto! Lo avete aiutato molto!

the webmaster RULLLLES!!

luogo grande, disegno piacevole….O

Aucuns doutes c’est une bonne page..

Ringraziamenti molto! Lo avete aiutato molto!

Great site, nice design

what a nice site. i like it, yeah, I do!)))

Ist hier viel erledigte Arbeit, offensichtlich. Guter Aufstellungsort !~

Aucuns doutes c’est une bonne page..

Grand emplacement - le bon travail ! ! !