viernes, 17 de septiembre de 2010

Conversión implícita de tipos

Es común escribir nuevas clases que expandan a las básicas del lenguaje.

Uno de los problemas que nos podemos encontrar cuando hacemos esto es la conversión de tipos.

Si por ejemplo creamos una nueva clase para manejar cadenas, el código se llenará rápidamente de castings para convertir las cadenas nativas del lenguaje a nuestra implementación. Esto ocurre sobre todo en lenguajes fuertemente tipados.

C# provee una solución bastante elegante, la conversión implícita de tipos.

Para mostrar el uso de esta característica se muestra una clase con dos tipos, una cadena y un entero y sus declaraciones de conversiones implícitas.

public class MyClass
{
private string str { get; set; }
private int number { get; set; }

public static implicit operator MyClass(string s)
{
MyClass ms = new MyClass();
ms.str = s;
return ms;
}

public static implicit operator MyClass(int i)
{
MyClass ms = new MyClass();
ms.number = i;
return ms;
}

public string getStr()
{
return str;
}

public int getNumber()
{
return number;
}
}

Declarando un operador estático, implícito y público se consigue la sintaxis siguiente para la conversión de tipos.

MyClass ms1 = "hello";
MyClass ms2 = 2;

Console.WriteLine(ms1.getStr());
Console.WriteLine(ms2.getNumber());

En el ejemplo se puede ver que no es necesaria ninguna conversión, y se pasan tanto la cadena "hello" como el entero 2 a tipo MyClass.

domingo, 12 de septiembre de 2010

Extension methods en c#

En algunos lenguajes dinámicos como ruby las clases se denominan "abiertas".
Esto significa que a cualquier clase se le puede añadir nuevos métodos o funcionalidades en tiempo de ejecución.

Los lenguajes fuertemente tipados no suelen ofrecer tanta libertad, pero se disponen de otras herramientas.

En C#, se pueden definir clases parciales, lo que significa que se puede definir el comportamiento de la clase en varias etapas.

public partial class PartialClass
{
public static void method1()
{
Console.WriteLine("method1");
}
}
...
public partial class PartialClass
{
public static void method2()
{
Console.WriteLine("method2");
}
}

Manteniendo las clases como parciales en cualquier momento se puede añadir funcionalidad a una clase existente fuera de su definición original.

Este método es útil tan solo para las clases que programamos, pero si queremos extender una librería externa o las clases del propio lenguaje las clases parciales no son de gran ayuda.

C# tiene en cambio una posibilidad más interesante, los "extension methods".

public static class ExtensionMethods
{
public static string withDot(this string str)
{
return str + ".";
}
}
...
string str = "text ";
str.withDot();

Con el código anterior se le añade a la clase string el nuevo método (withDot).
Para hacer lo mismo sin "extension methods" habría sido necesario crear una nueva clase que heredara de string y añadirle el método withDot.

Gracias a los "extension methods" se puede evitar crear clases intermedias para extender funcionalidades de las ya existentes.