127.0.0.1: Hogar dulce hogar

viernes, 4 de febrero de 2011

[C#] Instancias en runtime de tipos dinámicos

 

Durante el desarrollo de algunas herramientas es necesario generalizarlas para poder reutilizarlas posteriormente, pero manteniendo siempre una funcionalidad concreta. En el caso que nos ocupa, quiero poder listar una serie de atributos genéricos y poder operar con ellos en la precisión deseada, pero partiendo de la premisa anterior. Es decir, no tendré una clase que disponga de algo similar:

  1. public class A
  2.         {
  3.             int a;
  4.             float b;
  5.             int c;
  6.             UInt16 x;
  7.         }

Esto es muy costoso de mantener en futuros proyectos, puesto que estaría obligado a cambiar manualmente todos los atributos del objeto y sus nombres pese a que el comportamiento puede estar definido, puesto que sólo me interesa poder operar con los números.

¿Solución? Pues muy sencillo. Por un lado, vamos a almacenar únicamente el  nombre de atributo junto con su tipo y valor, todo con string. Posteriormente usaremos reflection para cargar el tipo de forma dinámica. Hasta aquí todo es correcto, nuestro mayor problema será que el evidentemente esos objetos dinámicos no son tipados y el compilador no sabrá qué son salvo que lo especifiquemos explícitamente mediante un casting. Es por ello que aquí entran los tipos dinámicos.

Los tipos dinámicos (o dynamic type, en inglés) es una nueva feature de C# 4.0. Recomiendo la lectura de la documentación para no caer en el error de confundirlos con los tipos anónimos. Debemos tener en cuenta que lo que queremos es operar con ellos en tiempo de ejecución, por lo que toda operación no soportada en tiempo de compilación por un tipo no nos servirá. De ahí que los tipos anónimos no sirva para el siguiente ejemplo, ya que no puedo operar entre objetos sin especificar explícitamente qué quiero hacer.

Es por ello que una vez tenemos el tipo deseado a instanciar mediante Reflection, podemos asignarle el valor y el tipo a la variable dinámica. Y podremos operar con ellos como si se tratase de tipos compilados previamente. Veamos un ejemplo:

  1. class Program
  2.     {
  3.         static void Main(string[] args)
  4.         {
  5.             string uno = "1";
  6.             string dos = "2,5";
  7.  
  8.             dynamic a = Convert.ChangeType(uno, Type.GetType("System.Single"));
  9.             dynamic b = Convert.ChangeType(dos, Type.GetType("System.Single"));
  10.  
  11.             Console.Out.WriteLine(a);
  12.             Console.Out.WriteLine(b);
  13.             Console.Out.WriteLine(a+b);
  14.             Console.Out.WriteLine(a-b);
  15.             Console.Out.WriteLine(a*b);
  16.             Console.Out.WriteLine(a/b);
  17.             Console.ReadLine();
  18.         }
  19.     }

A través de Type.GetType() uso Reflection para cargar el tipo que quiero instanciar. Con Convert.ChangeType asigno un valor a un tipo, y todo ello a una variable dinámica. De este modo podremos operar con los números como si se tratasen de floats.

jueves, 6 de enero de 2011

[Ebooks] Libros GRATIS de Rob Miles!

Hoy que vienen los Reyes Magos, os traigo unos cuantos ebooks en pdf de Rob Miles. Los podéis encontrar aquí, aunque pongo los que más puedan interesar en un principio:

CSharp from Java Orange Book: Este libro está destinado para programadores de Java que desean trabajar con CSharp.

CSharp Yellow Book 2010: Un buen libro para introducirse en CSharp. Poco se puede añadir.

miércoles, 5 de enero de 2011

[WP7] My Borrowed List

¿Has prestado tus apuntes a alguien y no recuerdas a quién? ¿Ni cuando? ¿Quién tiene tu libro favorito?¿Cuándo le dejaste a tu primo tu último videojuego? Pues para gestionar esto tengo el placer de presentar otra aplicación mía que recientemente ha aparecido en el Windows Phone Marketplace: My Borrowed List.

 

List

A través de esta sencilla aplicación puedes gestionar qué has prestado, a quién se lo has prestado, cuándo se lo has prestado y el valor del objeto que prestas.

Como siempre, estaré encantado de recibir feedback de la aplicación. Si la quieres probar, puedes descargarla a través de aquí. Por cierto, la aplicación es gratis!

viernes, 31 de diciembre de 2010

[WP7] My Calculator

Recientemente he subido una nueva aplicación en el Marketplace de WP7. Es una calculadora científica, pensada para ingenieros informáticos. Como tal siempre he deseado tener en el móvil una calculadora en la que pudiera convertir (entre otras cosas) números de diferente base sin necesidad de usar la calculadora de Windows o el papel en su defecto. Con My Calculator puedes trabajar con el sistema decimal, radián, binario, hexadecimal y octal. Seguiré trabajando para añadirle features en el futuro. Como siempre, cualquier sugerencia será bien recibida, de igual manera si se encuentra algún bug intentaré ser lo más rápido posible en solventarlo.

calculator

La aplicación la puedes descargar aquí, por 0,99€

miércoles, 29 de diciembre de 2010

[C#] Extension Methods

Con la irrupción de LINQ, el lenguaje se debe adaptar a nuevos usos que agilicen la potencia que proporciona LINQ. Fruto de esta necesidad se incluyó en C# 3.0 los llamados “Extension Methods”. Estos métodos tienen la finalidad, como su propio nombre indica, para extender clases. Y esto puede ser interesante cuando deseo que una clase tenga determinado funcionalidad, propia de un “tipo” derivado pero sin la suficientemente intensidad para crear un tipo derivado a propósito.

Para implementarlo, es muy sencillo. Se debe crear un método estático dentro de una clase estática. A este método le pasaremos un parámetro a través del puntero this, que indica el tipo al que se asociará este método junto con los parámetros que se requieran. Por ejemplo, vamos a extender un tipo base como int con un nuevo método, que llamaremos TestInt() que comprobará cuándo el número es mayor que 0.

   1: public static class Extensions
   2:     {
   3:         public static bool TestInteger(this int number)
   4:         {
   5:             if (number > 0)
   6:             {
   7:                 return true;
   8:             }
   9:             return false;
  10:         }
  11:     }

Luego sencillamente podremos aplicar esto a todos los tipos int, siempre y cuando el acceso al namespace para que encuentre la clase Extensions. Véase el siguiente ejemplo:

   1: public class Item
   2:    {
   3:        int index;
   4:  
   5:        public Item()
   6:        {
   7:            if (index.TestInteger())
   8:            { }
   9:        }
  10:    }

Como se puede apreciar esto es algo bueno, bonito y barato, pero muy arriesgado. Se recomienda usarlo sobre nuestros tipos y siempre que sea posible dedicado a consultas de tipo LINQ o eventos. No debemos usarlo con tipos base (como es el caso) o sobre tipos que no son nuestros porque puede cambiar la implementación en el futuro y posiblemente, tengamos problemas de compatibilidad.

lunes, 27 de diciembre de 2010

[Silverlight] Convirtiendo tipos para DataTemplates

Una de las armas más poderosas de WPF y Silverlight son los DataTemplates, que te permiten especificar un template y después mediante el DataBinding puedes desplegar todos los datos de forma automática sin necesidad de rellenarlos a “pelo” insertando fila por fila.

Pero en algunas ocasiones se necesitará contemplar elementos que deben aparecer o no en función de algunos valores de lógica. Por ejemplo, en mi lógica dispongo de una clase Item que tiene una propiedad booleana llamada Borrowed. Cuando esta propiedad está a true, debe aparecer un botón, y cuando no lo está, no debe aparecer nada. En Silverlight la propiedad Visibility permite especificar la visibilidad de un elemento cualquiera, pero esta propiedad se ajusta a través de un enumerado que indica si es visible ( Visible ) o no (Collapsed). Como medida sucia podría incluir dentro de mi lógica una propiedad que tuviera ese valor, pero entonces estaría causando una dependencia entre la lógica y la interfaz de la aplicación y como todos sabemos, eso nunca es bueno. Para solventar este tipo de cosas usaremos un Converter junto con el Binding. Vayamos por partes.

Usaremos el converter para transformar el valor de una propiedad en otro. En nuestro caso, transformaremos el valor booleano de Borrowed por el valor Visible de la interfaz. Para ello crearemos una clase que implemente la interfaz IValueConverter. Esta interfaz consta de dos métodos, Convert y ConvertBack. En nuestro caso vamos a implementar únicamente el Convert, ya que el ConverBack se usará en sentido inverso (de interfaz a lógica).

   1: public class BorrowedToVisibilityConverter : System.Windows.Data.IValueConverter
   2:     {
   3:         #region IValueConverter Members
   4:  
   5:         public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   6:         {
   7:             Visibility isVisible = Visibility.Collapsed;
   8:             if ((value == null))
   9:                 return isVisible;
  10:             if (((bool)value))
  11:             {
  12:                 isVisible = Visibility.Visible;
  13:             }
  14:             return isVisible;
  15:         }
  16:  
  17:         public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  18:         {
  19:             throw new NotImplementedException();
  20:         }
  21:  
  22:         #endregion


Dentro de Convert interesa el parámetro value (lo que vamos a usar para convertir). El resto de parámetros no interesa en este caso, pero no es necesario explicarlos. Como se puede apreciar el código es sencillo, si el valor es positivo se devuelve Visibility.Visible y en cualquier otro caso se devuelve Visibiliy.Collapsed. Ahora teniendo esto ya implementado, tenemos que asociarlo a nuestro binding y por ello, a partir de este momento nos dedicamos ya con el fichero XAML correspondiente.

Ante de asociarlo, tenemos que mapear este conversor como un recurso. Para ello simplemente le asignamos una clave de referencia y especificamos el nombre del conversor:

   1: <UserControl.Resources>
   2:          <converter:BorrowedToVisibilityConverter x:Key="BorrowedToVisibility" />
   3: </UserControl.Resources>

Y por último lo asociamos a nuestro binding. En este caso irá en un botón en el su propiedad Visibility dependerá del valor de la propiedad Borrowed del binding asociado al template. Es aquí cuando ya debemos especificar el conversor de forma explícita:

   1: <Button Content="Ok!" Height="72" Width="160"  Visibility="{Binding Borrowed, Converter={StaticResource BorrowedToVisibility} }" HorizontalAlignment="Right" Click="Button_Click" Tag="{Binding Id}" Background="White" BorderBrush="Black" Foreground="Black" />

Y más en detalle:

   1: Visibility="{Binding Borrowed, Converter={StaticResource BorrowedToVisibility} }" 

Asociamos la propiedad del objeto y le indicamos que tenemos un conversor, incluido como recurso estático y su clave de referencia.

jueves, 16 de diciembre de 2010

[Ebooks] Libro GRATIS Windows Phone programming in C#

A través de Rob Miles nos cuenta que han publicado su curso de programación para Windows Phone 7 en Microsoft Faculty Center.

Windows Phone 7 Blue Book

Este libro es una introducción para Windows Phone 7 para cualquier persona que tenga fundamentos muy básicos de programación. Cuenta con ocho capítulos (WP7, Introducción a Silverlight,Introducción a Visual Studio 2010, Interfaces con Silverlight, Consumo de servicios, XNA, Creando aplicaciones para WP7 y Windows Phone Marketplace).

Descárgalo a través de este enlace. ¡Que aproveche!