Sei sulla pagina 1di 8

TRUCO: Cmo obtener los nombres de una enumeracin

Escrito por Jos Manuel Alarcn el 3 abril 2014 11:00

En muchos programas se suelen dar a los usuarios una serie de opciones para que escoja. Por ejemplo un
tipo de bsqueda a realizar, un rango de posibles valores para parametrizar algn comportamiento, etc...
Lo ms habitual es que estas opciones se "mapeen" despus a elementos de una enumeracin en el
cdigo de la capa de negocio. De esta forma si definimos una similar a esta:
public enum EstadoCivil
{
Casado,
Soltero,
Divorciado,
Viudo,
Religioso,
}

Lo ms comn ser que en la interfaz de usuario exista un modo de seleccionar algn valor equivalente,
por ejemplo a travs de una lista desplegable o un conjunto de botones de radio.
Es bastante habitual generar los elementos de la interfaz manualmente, aadiendo opciones a una lista
Web o Windows, por ejemplo, con cdigo similar a este:
lista.Items.Add(new ListItem("Casado", "0");
lista.Items.Add(new ListItem("Soltero", "1");

etc...

Sin embargo, sera muy til poder aadir automticamente los valores de una enumeracin cualquiera
sin preocuparse por saber cuntas son o cul es su nombre. Gracias al poder de la reflexin en .NET esto
es algo muy sencillo de conseguir.
Por ejemplo, la siguiente funcin toma como argumentos una referencia a un control de lista cualquiera
de .NET (ListBox, CheckBoxList, DropDownList, etc...) y un valor enumerado cualquiera y rellena el
control con tantas opciones como tenga disponibles dicha enumeracin:
private void Enlaza(ListControl lst, Enum e)
{
string[] valores = Enum.GetNames(e.GetType());

foreach (string valor in valores)


lst.Items.Add(valor);
}

Toda la clave est en el mtodo GetNames del tipo Enum, que devuelve una matriz con los nombres de
cada elemento de la enumeracin indicada. As, para rellenar una lista slo hay que escribir, por
ejemplo:
Enlaza(miListBox, EstadoCivil.Casado);

O sea, se le pasa una referencia al control de lista y un miembro cualquiera de la enumeracin.


Fcil verdad?
La anterior funcin es muy sencilla pero puede dar algunos problemas. Por ejemplo, si al definir la
enumeracin se han declarado algunos miembros con valores especficos y diferentes a los valores por
defecto, entonces el orden en la lista no coincidir con el valor de cada miembro (0, 1, 2...). Se puede
arreglar, pero complica algo la funcin. El cdigo definitivo es el siguiente:
private void Enlaza(ListControl lst, Enum e)
{
Type tipo = Enum.GetUnderlyingType(e.GetType());
string[] nombres = Enum.GetNames(e.GetType());
Array valores = Enum.GetValues(e.GetType());
for (int i = 0; i < nombres.Length; i++)
lst.Items.Add(new ListItem(nombres[i], Convert.ChangeType(valores.GetValue(i),
tipo).ToString()));
}

Con esto ya queda totalmente definido. Se convierte cada uno de los valores a su tipo subyacente (para
obtener su valor numrico, no su nombre) y luego se convierte en una cadena para aadirlo al ListItem.
Lo bueno de este cdigo es que, aunque un poco ms complicado permite trabajar de forma genrica
con cualquier enumeracin, sin importar su tipo o la cantidad de elementos que tenga.
Se puede retocar la funcin para que, si se desea, se aada opcionalmente un elemento extra al principio
o al final para permitir que el usuario escoja otra opcin (por ejemplo, "Otro", "Ninguno",
"[Cualquiera]"... dependiendo del contexto).

TRUCO: Cmo lanzar un proceso y recoger los resultados de su ejecucin


Escrito por campusMVP el 8 mayo 2014 11:00
Hay ocasiones en las que es necesario poder lanzar un programa de lnea de comandos (o no) de
modo silencioso para realizar una tarea y luego recoger de algn modo el resultado de su ejecucin. Un
caso tpico es el envo de archivos por FTP.
FTP.exe es un ejecutable muy til que viene con Windows y que permite enviar rdenes a un servidor
de archivos mediante un archivo de comandos que se le pasa como parmetro.
La siguiente funcin sirve para ejecutar cualquier programa con su ventana (de haberla) oculta,
devolviendo el resultado de la ejecucin en una cadena (normalmente lo que aparecera en la lnea de
comandos):

private static string lanzaProceso(string Proceso, string Parametros)


{
ProcessStartInfo startInfo = new ProcessStartInfo(Proceso, Parametros);
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.UseShellExecute = false; //No utiliza RunDLL32 para lanzarlo
//Redirige las salidas y los errores
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
Process proc = Process.Start(startInfo); //Ejecuta el proceso
proc.WaitForExit(); // Espera a que termine el proceso
string error = proc.StandardError.ReadToEnd();
if (error != null && error != "") //Error
throw new Exception("Se ha producido un error al ejecutar el proceso '" + Proceso +
"'\n" + "Detalles:\n" + "Error: " + error);
else //xito
return proc.StandardOutput.ReadToEnd(); //Devuelve el resultado
}

Si se produce un error se lanza una excepcin que recoge los detalles enviados por el programa a la lnea
de comandos. Puede resultar muy til. Es necesario incluir System.Diagnostics.

TRUCO: La manera correcta de averiguar el separador decimal y otros


datos sobre nmeros en .Net
Escrito por campusMVP el 22 mayo 2014 11:00
Aunque pueda parecer una tontera, seguramente te sorprenderas de saber la cantidad de proyectos que
aparecen con fallos y excepciones no controladas por el mero hecho de no hacer bien la conversin de
nmeros, desde los valores que introduce un usuario al tipo de dato adecuado.
As, muchos hacen caso omiso de los maravillosos mtodos Parse o TryParse que todos los tipos
numricos nos ofrecen, y tratan de convertirlos usando sus propios sistemas. Este tipo de programacin
viene heredada de tiempos peores, antes de .NET, y hay que desterrarlas.
Al igual que pasa con los nmeros tambin suele haber problemas
con las fechas, aunque por suerte en este caso gracias a la
existencia de selectores visuales de fecha los problemas se
minimizan.
Hay una pregunta interesante que surge en muchas ocasiones en el
mbito de esta problemtica y es cmo podemos saber el
formato de un nmero en la cultura actual del sistema de
nuestro usuario?
Para responderlo hay mtodos de todos los tipos: desde el que convierte en cadena el resultado de dividir
dos nmeros y extrae el primer carcter no numrico desde el final para averiguar el separador de
decimales, hasta el que simplemente supone siempre que el separador va a ser una coma (sin contar con
la gran diversidad del mundo). Cul es la mejor forma de averiguar estas cosas en .NET?
La clase NumberFormat tiene la respuesta. El siguiente cdigo nos da la informacin que necesitamos:
using System.Globalization;
NumberFormatInfo nfi = System.Globalization.CultureInfo.CurrentCulture.NumberFormat;
string SeparadorDecimal = nfi.NumberDecimalSeparator;
string separadorDeMiles = nfi.NumberGroupSeparator;

string signoNegativo = nfi.NegativeSign;

Interesante y fcil verdad?


Otro truco y ms material para investigar: cmo puedo averiguar los nombres de los das de la semana
en la cultura actual? Solucin: la clase DateTimeFormatInfo
DateTimeFormatInfo dtfi = System.Globalization.DateTimeFormatInfo.CurrentInfo;
string[] nombresDias = dtfi.DayNames;

Y tienes una bonita matriz con los das de la semana en el idioma que quieras, empezando por el
domingo.

Chuleta: Formato de cadenas de texto en .NET


Escrito por campusMVP el 23 abril 2014 11:00
La plataforma .NET proporciona un sistema exhaustivo, flexible y consistente para poder representar de manera textual
cualquier tipo de datos numricos, de fecha y hora e incluso enumeraciones.
El formato de un dato est controlado mediante cadenas de texto que representan diferentes estilos, estndar o
personalizados, y que nos sirven para determinar con exactitud cmo queremos que se visualicen los valores cuando
hay que convertirlos a texto.
Adems de esto, la plataforma .NET tiene en cuenta una cuestin avanzada como son los ajustes culturales del
usuario actual. De este modo un mismo formato puede ser representado de manera muy diferente en funcin del
idioma y de los ajustes regionales de los usuarios de nuestras aplicaciones. Por ejemplo, en Espaa la fecha 22 de Abril
de 2014 se expresa en formato de fecha corta como 22/04/2014. Sin embargo en formato de fecha corta en ingls
americano el mes va siempre en primer lugar, por lo que se mostrara como 04/22/2014. La plataforma tiene en cuenta
estas particularidades e incluso se encarga de traducir al idioma apropiado los nombres de los das de la semana o de
los meses.
Existen muchos mtodos para dar formato a un dato, pero los ms comunes son dos:

Utilizar el mtodo Format de la clase String. Por


ejemplo:Console.WriteLine(String.Format("Hoy es {0:D}",

DateTime.Now)); que mostrara la cadena Hoy es seguida de la fecha actual en formato largo y en el
idioma del usuario actual.

Utilizar el mtodo ToString de los distintos tipos pasndole la cadena de formato como parmetro. Por
ejemplo: Console.WriteLine(DateTime.Now.ToString("D")); que mostrara la fecha actual
en formato largo y en el idioma local.

A continuacin hemos resumido en una prctica tabla los diferentes formatos estndar para los distintos tipos, y los
formatos personalizables para crear nuestras propias representaciones. Todos ellos se acompaan de ejemplos y sus
resultados para el idioma espaol y regin Espaa.
Excepto que se especifique explcitamente en la propia tabla, los especificadores estndar funcionan tanto en
minsculas como en maysculas.

Si lo deseas puedes descargar esta chuleta en formato PDF para facilitar su impresin y poder tenerla siempre a mano
en tu escritorio.

Nmeros
Especificadores de formato numrico bsico (en MSDN)
Especificador Tipo

Formato

Salida (con 1.23, doble)

Salida (con -12300,


entero)

Divisa/Moneda

{0:c}

1,23

-12,300,00

Decimal (solo funciona con


nmeros enteros)

{0:d}

System.FormatException -12300

Notacin cientfica

{0:e}

1,230000e+000

-1,230000e+004

Especificador Tipo

Formato

Salida (con 1.23, doble)

Salida (con -12300,


entero)

Punto fijo

{0:f}

1,23

-12300,00

General

{0:g}

1,23

-12300

Numero con separador de


miles

{0:n}

1,23

-12.300,00

Convertible en ambos sentidos

{0:r}

1,23

System.FormatException

Hexadecimal

{0:x}

System.FormatException ffffcff4

Porcentaje

{0:p}

123,00 %

-1.230.000,00 %

Especificadores de formato numrico personalizables (en MSDN)

Especificador Tipo

Ejemplo

Salida(con
1234.56,
doble)

Observaciones

{0:00.0000} 1234,5600

Rellena con ceros si es necesario, en este caso


llevar dos dgitos mnimo antes de la coma y cuatro
decimales. El punto representa el separador decimal
que corresponda a la cultura actual (una coma en
Espaa).

Marcador de
posicin de
dgito

{0:(#).#}

(1234),5

Rellena cada posicin con dgitos si existen, sino no


pone nada, y si hay de ms los omite en los
decimales.

Punto decimal

{0:0.0}

1234,5

Separador de
miles

{0:0,0}

1.234

Porcentaje

{0:0.0%}

123456,0 %

Tanto por mil

{0:0.0}

1234560,0 % Multiplica por 1000, aade el smbolo de %

Marcador de
posicin 0

Notacin
exponencial

Separador de
seccin

{0:00e+0}

12e+2

Multiplica por 100, aade el smbolo de %

El nmero de cero indica el nmero mnimo de


dgitos en el exponente. El "+" fuerza a poner el
signo siempre delante del exponente, y el "-" solo
cuando es un exponente negativo.
Define secciones con formatos diferentes para
nmeros positivos, negativos y el cero. Tiene
bastantes opciones. Ver MSDN. Es especialmente
til para dar formato a valores de divisas que
requieran poner valores negativos entre parntesis.

Fechas
Especificadores estndar para fechas (en MSDN)
Especificador

Tipo

Ejemplo

Fecha corta

22/04/2014

Fecha larga

martes, 22 de abril de 2014

Hora corta

18:19

Hora larga

18:19:47

Fecha y hora completa

martes, 22 de abril de 2014 18:19

Fecha y hora completa (largo)

martes, 22 de abril de 2014 18:19:47

Fecha y hora por defecto

22/04/2014 18:19

Fecha y hora por defecto (largo)

22/04/2014 18:19:47

Patrn mes da

22 abril

Fecha en formato RFC1123

Wed, 16 Apr 2014 18:19:47 GMT

Fecha ordenable

2014-04-22T18:19:47

Universal ordenable

2014-04-22 18:19:47Z

Universal completa

martes, 22 de abril de 2014 18:19:47

Patrn ao, mes

abril de 2014

Convertible en ambos sentidos

2014-04-22T18:19:47.9980451 +02:00

Especificadores personalizados para fechas (en MSDN)


Especificador

Tipo

Ejemplo

Ejemplo Salida

dd

Da

{0:dd}

22

ddd

Nombre del da corto

{0:ddd}

mar

dddd

Nombre del da completo

{0:dddd}

martes

Fracciones de segundo

{0:ffff}

5960

Era (antes de Cristo, etc...)

{0:gg}

DC

f, ff, fff, ffff


gg

Especificador

Tipo

Ejemplo

Ejemplo Salida

hh

hora (entre 1 y 12)

{0:hh}

06

HH

hora (dos dgitos), formato 24 horas

{0:HH}

18

mm

Minutos 00-59

{0:mm}

19

MM

Mes 01-12

{0:MM}

04

Mes (abreviacin)

{0:MMM}

abr

Mes (nombre completo)

{0:MMMM}

abril

Segundos 0-59

{0:s}

47

ss

Segundos 00-59 (rellena con cero)

{0:ss}

47

tt

AM o PM

{0:tt}

PM

yy

Ao (2 dgitos)

{0:yy}

14

Ao

{0:yyyy}

2014

Diferencia horaria respecto a GMT

{0:%z}

+2

zz

Diferencia horaria (2 dgitos) respecto a GMT

{0:zz}

+02

zzz

Diferencia horaria (completo) respecto a GMT

{0:zzz}

+05:00

Separador de lo anterior

{0:hh:mm:ss}

04:40:47

Separador de lo anterior

{0:dd/MM/yyyy}

20/04/2014

MMM
MMMM

yyyy

Enumeraciones
Especificadores estndar para enumeraciones (en MSDN)
Especificador

Tipo

Valor por defecto (nombres de flags si estn disponibles, si no, el entero correspondiente)

Siempre nombres de flags

Siempre enteros

Ocho dgitos hexadecimal

Potrebbero piacerti anche