Macro sustitución en C#

Una de las características de Visual Foxpro (mi anterior lenguaje antes de .net) y del que todos los días me acuerdo cuando me peleo con .net, era la utilización de macro sustitución, esta permitía realizar cosas como la siguiente:

   1: FOR i = 1 TO 12

   2:    xcam = 'Formas_pago.poraplaza' + ALLTRIM(STR(i))

   3:    IF &xcam > 0

   4:    ENDIF

   5: ENDFOR

De esta forma utilizando el símbolo &, podía evaluar el contenido de los campos sin tener que escribirlos uno a uno y ahorrando líneas de código.

Por desgracia c# no posee esta característica con un uso tan sencillo, se pueden realizar aproximaciones compilando el código al vuelo con codedoom o similares, pero personalmente evitaria utilizar estas técnicas si no es absolutamente necesario.

Ya metidos en harina, estaba en .net transcribiendo un bloque de código desde Fox y claro el pequeño programa de arriba daba lugar a un programa similar a este:

   1: /// Carga la configuración dependiente de la forma de pago correspondiente

   2: if (!string.IsNullOrEmpty(cvc.Forma_pago))

   3: {

   4:     using (ManagerBI<Formas_pago> manager = new ManagerBI<Formas_pago>() )

   5:     {

   6:         if (manager.GetRecord(cvc.Forma_pago))

   7:         {

   8:             cvc.PorcentajesAplazamientoAdd(manager.Data.Porcentaje_aplazamiento_1);

   9:             cvc.PorcentajesAplazamientoAdd(manager.Data.Porcentaje_aplazamiento_2);

  10:             cvc.PorcentajesAplazamientoAdd(manager.Data.Porcentaje_aplazamiento_3);

  11:             cvc.PorcentajesAplazamientoAdd(manager.Data.Porcentaje_aplazamiento_4);

  12:             cvc.PorcentajesAplazamientoAdd(manager.Data.Porcentaje_aplazamiento_5);

  13:             cvc.PorcentajesAplazamientoAdd(manager.Data.Porcentaje_aplazamiento_6);

  14:             cvc.PorcentajesAplazamientoAdd(manager.Data.Porcentaje_aplazamiento_7);

  15:             cvc.PorcentajesAplazamientoAdd(manager.Data.Porcentaje_aplazamiento_8);

  16:             cvc.PorcentajesAplazamientoAdd(manager.Data.Porcentaje_aplazamiento_9);

  17:             cvc.PorcentajesAplazamientoAdd(manager.Data.Porcentaje_aplazamiento_10);

  18:             cvc.PorcentajesAplazamientoAdd(manager.Data.Porcentaje_aplazamiento_11);

  19:             cvc.PorcentajesAplazamientoAdd(manager.Data.Porcentaje_aplazamiento_12);

  20:  

  21:             cvc.DiasPagoAdd(manager.Data.Dia_pago_1);

  22:             cvc.DiasPagoAdd(manager.Data.Dia_pago_2);

  23:             cvc.DiasPagoAdd(manager.Data.Dia_pago_3);

  24:             cvc.DiasPagoAdd(manager.Data.Dia_pago_4);

  25:             cvc.DiasPagoAdd(manager.Data.Dia_pago_5);

  26:             cvc.DiasPagoAdd(manager.Data.Dia_pago_6);

  27:             cvc.DiasPagoAdd(manager.Data.Dia_pago_7);

  28:             cvc.DiasPagoAdd(manager.Data.Dia_pago_8);

  29:             cvc.DiasPagoAdd(manager.Data.Dia_pago_9);

  30:             cvc.DiasPagoAdd(manager.Data.Dia_pago_10);

  31:             cvc.DiasPagoAdd(manager.Data.Dia_pago_11);

  32:             cvc.DiasPagoAdd(manager.Data.Dia_pago_12);

  33:  

  34:             cvc.DiasAplazamientoAdd(manager.Data.Dias_aplazamiento_1);

  35:             cvc.DiasAplazamientoAdd(manager.Data.Dias_aplazamiento_2);

  36:             cvc.DiasAplazamientoAdd(manager.Data.Dias_aplazamiento_3);

  37:             cvc.DiasAplazamientoAdd(manager.Data.Dias_aplazamiento_4);

  38:             cvc.DiasAplazamientoAdd(manager.Data.Dias_aplazamiento_5);

  39:             cvc.DiasAplazamientoAdd(manager.Data.Dias_aplazamiento_6);

  40:             cvc.DiasAplazamientoAdd(manager.Data.Dias_aplazamiento_7);

  41:             cvc.DiasAplazamientoAdd(manager.Data.Dias_aplazamiento_8);

  42:             cvc.DiasAplazamientoAdd(manager.Data.Dias_aplazamiento_9);

  43:             cvc.DiasAplazamientoAdd(manager.Data.Dias_aplazamiento_10);

  44:             cvc.DiasAplazamientoAdd(manager.Data.Dias_aplazamiento_11);

  45:             cvc.DiasAplazamientoAdd(manager.Data.Dias_aplazamiento_12);

  46:         }

  47:     }

  48: }

Qué horror, 36 líneas para hacer lo mismo, pero imaginar que en lugar de 36 campos tuviéramos 100. Se me ocurrió la idea de usar reflection para poder evitar la escritura de tantas  líneas y resulto relativamente fácil, la solución es interesante y en casos similares os permitirá reducir en gran medida vuestro código. El rendimiento de reflexión apenas penalizará la aplicación.

   1: /// Carga la configuración dependiente de la forma de pago correspondiente

   2: if (!string.IsNullOrEmpty(cvc.Forma_pago))

   3: {

   4:     using (ManagerBI<Formas_pago> manager = new ManagerBI<Formas_pago>() )

   5:     {

   6:         if (manager.GetRecord(cvc.Forma_pago))

   7:         {

   8:             Type t = manager.Data.GetType();

   9:  

  10:             for (int i = 1; i < 12; i++)

  11:             {

  12:                 string contador = i.ToString().Trim();

  13:                 decimal porcentajeAplazamiento = (decimal)t.InvokeMember("Porcentaje_aplazamiento_" + contador, BindingFlags.GetProperty, null, manager.Data, null, CultureInfo.CurrentCulture);

  14:                 cvc.PorcentajesAplazamientoAdd(porcentajeAplazamiento);

  15:                 byte diaPago = (byte)t.InvokeMember("Dia_pago_" + contador, BindingFlags.GetProperty, null, manager.Data, null, CultureInfo.CurrentCulture);

  16:                 cvc.DiasPagoAdd(diaPago);

  17:                 Int16 diasAplazamiento = (Int16)t.InvokeMember("Dias_aplazamiento_" + contador, BindingFlags.GetProperty, null, manager.Data, null, CultureInfo.CurrentCulture);

  18:                 cvc.DiasAplazamientoAdd(diasAplazamiento);

  19:             }

  20:         }

  21:     }

  22: }

Espero que os sirva.
 

2 comentarios en “Macro sustitución en C#”

  1. Hola buena tarde. estoy analizando el ejemplo que publicas y me parece super interesante, pero hay algo que no logro entender, qué es ManagerBI Formas_pago me imagino que es un campo (un textbox) y qué es ManagerBI o como se declara o de dónde proviene. Expreso mis agradecimientos por la colaboración prestada.

  2. Forms_pago es un entidad de nuestro modelo de datos, como puede ser clientes, articulo o cualquier otra, es un simple ejemplo y refleja el nombre de la entidad, que en este caso se corresponde a una clase. ManagerBI es un clase genérica que permite que cualquier entidad pueda añadir, borrar o buscar registros, esto se puede desarrollar con EF o cualquier modelo de datos actual.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *