lunes, 26 de diciembre de 2016

Usando el control de validación CompareValidator ASP .NET - parte II

Como un complemento al primer ejercicio del control ASP .NET CompareValidator, aqui presento un segundo ejemplo que muestra como utilizar el control CompareValidator para comparar el valor de un control ASP.NET con un tipo específico de dato .NET (Currency, Date, Double, Integer, String) o bien comparar si teniendo dos valores: uno es menor o mayor al otro o si ambos valores son iguales.

Este segundo ejemplo consta de dos archivos: CompareValidatorSample2.aspx y CompareValidatorApp2.aspx.cs

Puedes descargar el código fuente aquí.

Fig 1 El ejemplo muestra la comparación de un valor contra un tipo específico de dato y la comparación del valor de un control contra el valor de otro control.

Fig 2 Comparando el valor de un control con un tipo específico de dato .NET.

Fig 3 Comparando el valor de un control contra el valor de otro control.

Algunas propiedades esenciales del control CompareValidator.

  • ControltoValidate: El control de donde obtendremos el valor a comparar
  • ControlToCompare: El control con el cual se compara el valor obtenido de la propiedad ControltoValidate
  • Display: Esta propiedad tiene 3 valores:
    1. Static: es la propiedad predeterminada, reserva un espacio suficiente en la página para mostrar el mensaje de error.
    2. Dynamic: el espacio para mostrar el mensaje no se reserva, cuando el mensaje se despliega se desplaza el contenido existente en la página.
    3. None: el mensaje no será desplegado en el lugar del control sino en el control ValidatorSummary si se localiza en la misma página.
  • Errormessage: el texto del mensaje que se desplegará si no se cumplen las condiciones.
  • Operator: La operación que efectuará el control en los valores de los campos, los valores son los siguientes:
    1. LessThan:El valor del ControlToValidate debe ser menor al valor del ControlToCompare.
    2. Equal: El valor del ControlToValidate debe ser igual al valor del ControlToCompare.
    3. NotEqual: El valor del ControlToValidate no debe ser igual al valor del ControlToCompare.
    4. LessThanEqual: El valor del ControlToValidate debe ser menor o igual al valor del ControlToCompare.
    5. GreaterThan: El valor del ControlToValidate debe ser mayor al valor del ControlToCompare.
    6. GreaterThanEqual: El valor del ControlToValidate debe ser mayor o igual al valor del ControlToCompare.
  • Type: El tipo de datos de los valores a comparar, los tipos de datos disponibles para este control son:
    1. Currency: Moneda
    2. Date: Fecha
    3. Double: Valor de punto flotante
    4. Integer: Entero sin punto decimal
    5. String: Cadena

miércoles, 21 de diciembre de 2016

Notas acerca de la recursión en C#

La recursión es una técnica de programación que se programa mediante un método que ya sea por iteración o por decisión resuelve un problema hasta llegar a un caso base , un método recursivo es un método que se llama así mismo ya sea directamente o indirectamente a través de otro método. Los enfoques recursivos para resolver problemas tienen varios elementos en común. El método en si sabe como resolver el o los casos más sencillos los llamados casos base.

Como un ejemplo ilustrativo, escribí un sencillo programa que contiene las funciones Fibonacci y factorial.

El programa se escribió en un proyecto Xamarin

Fig 1. El programa en el entorno de Xamarin

Para ejecutar el programa desde una consola de terminal, habilitar en el proyecto la opción "Run on external console"

Fig 2. Habilitando la opción "Run on external console"

Fig 3. El programa en ejecucción

lunes, 19 de diciembre de 2016

Usando los controles de validación ASP.NET IV (CompareValidator)

Otra de las tareas muy útiles al construir formularios para aplicaciones ASP.NET es poder comparar el valor de un control en el formulario con el valor de otro control, en estos casos se utiliza el control CompareValidator, este control también puede comparar el valor del control con un valor constante o si se requiere asegurarnos que ese valor sea del tipo de datos que nosotros necesitamos.

Como primer ejemplo de este control mostraré la una página ASP.NET con unos campos solicitando una contraseña y su confirmación.

Este primer ejemplo consta de dos archivos: CompareValidatorSample.aspx y Samples.ASP.CompareValidatorApp.aspx.cs.

Fig 1 Utilizando el control CompareValidator para confirmar contraseñas.

Fig 2 Si las contraseñas no son idénticas el control muestra un mensaje.

Fig 3 Si las contraseñas coinciden, se envían los datos al servidor.

miércoles, 14 de diciembre de 2016

Enumeraciones con C#

Un tipo de datos de enumeración enum es usado para definir un conjunto de elementos constantes, este tipo de datos se usan para agrupar constantes y en programas de opción múltiple. Las enumeraciones pueden ser de cualquier tipo de datos (integer, short, long) excepto el tipo de datos char.

Un breve ejemplo:

Ahora con esta enumeración podemos hacer un programa que tenga el siguiente método:

La ejecucción del programa producirá la siguiente salida.

Fig 1. La ejecucción del ejemplo de enumeraciones

domingo, 4 de diciembre de 2016

Entendiendo las expresiones lambda (lambda expressions) en C#

Introducción

La programación imperativa es uno de los paradigmas de computación mas ampliamente utilizados por la mayoría de lenguajes de programación de alto nivel debido al gran soporte académico y comercial y a que los programas son relativamente independientes del tipo de computadora donde se ejecutan porque los lenguajes de programación deben abstraer las operaciones del modelo de maquina para la cual se diseñaron.

La programación imperativa se basa en el modelo de la máquina de Von Neuman, del cual la mayoría de las computadoras personales y estaciones de trabajo tienen elementos comunes.

Aunque menos utilizado existe otro paradigma que a diferencia del imperativo se basa en las matemáticas (aplicación de funciones) con el cual igualmente podemos expresar operaciones computacionales de forma mas compacta y abstracta, este paradigma se conoce como programación funcional.

Uno de los muchos elementos del paradigma funcional que .NET incluye desde la versión 3.0 son las expresiones lambda (lambda expression).

Programación Funcional

Los conceptos básicos de la programación funcional datan de 1956 a 1958 con el trabajo de Jonh McCarthy en el desarrollo y diseno de LISP (List Processor), este lenguaje esta basado en el calculo lambda que sento las bases de los lenguajes funcionales, características como:

  • Recursión: se utiliza para para realizar operaciones repetitivas, no utiliza la iteración.
  • Funciones de primer orden: las funciones tienen el mismo nivel que cualquier otro elemento del lenguaje,pueden aplicarse a valores, evaluarse, regresar un valor y ser parámetros de otras funciones.
  • No requiere asignación: el computo se realiza aplicando funciones a los argumentos.
  • Garbage collector: Se reclaman los objetos que no están siendo utilizado por el programa.
  • Tipado dinámico (Dynamic typing): La comprobación del tipo se realiza en tiempo de ejecución, los valores tienen tipos, pero las variables no.

El paradigma funcional se basa en el concepto matemático de función, que la mayoria de los lenguajes de programación imperativos y funcionales comparten y cuya definición es

(1)Una función f es una regla que asigna a cada elemento x de un conjunto A exactamente un elemento llamado f(x) de conjunto B

Donde la programación funcional marca su diferencia con la imperativa es que para la programación funcional cada programa es equivalente a esta definición, donde x es el argumento o dominio de f mientras que y es el rango de f o la salida sea los programas son cajas negras donde solo importa el que se esta computando y no el como se esta computando que es el caso de la programación imperativa.

En resumen cuando se programa de forma funcional se piensa más en expresiones y su significado que en una secuencia de operaciones en memoria.

Tipos Delegate y métodos anónimos

Desde sus primeras versiones .NET introdujo el objeto delegate (delegado) que es un tipo particular de objeto (un delegate deriva de la clase base System.Delegate), que puede encapsular la referencia a un método estático o de una instancia como si fuera un mecanismo de callback(devolución de llamada) similar a los apuntadores de función de C y C++ pero con la importante diferencia de que proporciona un tipado seguro (type-safety) para evitar errores en tiempo de ejecución y que puedan detectarse en tiempo de compilación si la función no coincide con la firma del método al que hace referencia.

Esto posibilita en un contexto de programación orientada a objetos que los métodos pueden recibir como argumentos otros métodos además de tipos primitivos y de referencia. Veamos un ejemplo para ilustrar estos conceptos con C#.

En versiones anteriores a C# 2.0 (1.1,1.0) los delegate se utilizaban como parámetros, veamos el siguiente ejemplo que se compone de dos clases:

  1. La clase Temp.cs que es la clase que encapsula las operaciones.
  2. La clase Program.cs que es la clase principal que asigna los métodos al delegado.

Ejemplo 1.1 Uso de métodos como parámetros en C# 1.1 (descargar archivo aquí).

Observamos que los métodos que implementan la funcionalidad deben declararse de una manera completamente procedural e imperativa.
public static double GetCelsius(double fahrenheit)
  {
   return (fahrenheit - 32) * (5 / 9D);
  }

  public static double GetKelvin(double fahrenheit)
  {
   return fahrenheit + 460;
  }

Las versiones posteriores de C# al incorporar los métodos anónimos se acerca más a la programación funcional al asociar un bloque de código a un delegate sin necesidad de tener toda su implementación en un método sino dentro de la misma declaración del objeto, como se muestra en el siguiente código que es el mismo código anterior pero usando métodos anónimos.

Ejemplo 1.2 Uso de métodos como parámetros utilizando métodos anónimos (descargar archivo aquí).

Aquí observamos la diferencia con respecto al código anterior del Ejemplo 1.1.

    Console.WriteLine("{0} Fahrenheit = {1:0.00} Celsius", x, ApplyF(x,
    delegate (double fahrenheit)
   {
    return (fahrenheit - 32) * (5 / 9D);
   }));
   Console.WriteLine("{0} Fahrenheit = {1:0.00} Kelvin", x,
   ApplyF(x,
            delegate (double fahrenheit)
   {
    return fahrenheit + 460;
   }));

Expresiones Lambda (Lambda Expressions)

Las expresiones lambda provienen del cálculo lambda (lambda calculus) desarrollado por Alonzo Church en los años 1930’s como una notación para representar todas las funciones computables equivalentes a una máquina de Turing, todos los lenguajes funcionales pueden ser vistos como una variante sintáctica del cálculo lambda.

Las expresiones Lambda son útiles para sintetizar funciones con pocos parámetros que regresan algún valor, esta expresión consiste básicamente en una regla de sustitución que expresa tal cual una función o sea un mapeo de los elementos del conjunto dominio a los elementos de un codominio por ejemplo en la siguiente expresión:

        cuadrado : integer → integer donde cuadrado(n) = n²
    

Se reduce a una notación que produce una función anónima donde los únicos símbolos son la letra lambda (λ) y el punto (.).

    λn.n²

En la mayoría de los lenguajes funcionales las funciones anónimas son valores representados por la palabra reservada lambda, como el caso de LISP.

Lambda (n)(**n)

Aunque C# no utiliza los símbolos de la notación matemática lambda, el operador lambda es => que significa “tiende a” o “va hacia a”, la estructura de una expresión lambda en C# es:

(Argumentos de entrada) => (salida al procesarlos)
En caso de únicamente una variable la sintaxis es:
(x) => (x*x)
En caso de múltiples argumentos la sintaxis es:
(x,y,z) => ()

Aquí es importante saber que es el tipo delegate que dicta el tipo de los parámetros de entrada y de salida.

Ejemplo 1.3 Métodos como parámetros utilizando expresiones lambda.

Observamos que de los métodos anónimos a las expresiones Lambda, nos queda una sintaxis más legible y compacta.


ApplyF(x, (fahrenheit) => ((fahrenheit - 32) * (5 / 9D))));
ApplyF(x, (fahrenheit) => (fahrenheit + 460)));

Al ejecutar todos los programas observamos que el resultado es el mismo en cada uno, lo que cambio fue únicamente la sintaxis.
Fig 1. El resultado del código usando delegados.

Conclusión

Para los nuevos retos en el desarrollo de software, es importante que los lenguajes de programación incorporen características de un paradigma de programación diferente a ellos para extender sus capacidades y así poder expresar algoritmos de una manera compacta y más concisa esto da como resultado un código más legible.