Para definir un método extendido:
Agregamos el namespace “System.Runtime.CompilerServices” a la clausula Uses del nombre de espacio en donde estemos definiendo el método extendido. Este namespace contiene la definición de un atributo (el tema de los atributos se tratará más adelante) llamado “ExtensionAttribute” que nos servirá para extender el método. Para hacer uso del atributo anteponemos [Extension] antes de la definición de la clase y antes de la definición del método a extender.
- Agregamos el namespace “System.Runtime.CompilerServices” a la clausula Uses del nombre de espacio en donde estemos definiendo el método extendido. Este namespace contiene la definición de un atributo (el tema de los atributos se tratará más adelante) llamado “ExtensionAttribute” que nos servirá para extender el método. Para hacer uso del atributo anteponemos [Extension] antes de la definición de la clase y antes de la definición del método a extender.
- Definimos una clase estática que contenga el método a extender. Esta clase debe de ser visible para los clientes que la consuman.
- Definir el método a extender, este debe de ser un método de clase y debe de estar definido en la sección public de la clase.
- El primer parámetro del método especifica el tipo sobre el que él método opera.
- En el espacio de nombres en donde consumamos el método extendido agregamos a la clausula Uses el namespace que contiene la clase con el método de extendido.
- Ahora ya podemos llamar al método normalmente, como si este método fuera parte de la clase desde un principio.
NOTA:
El primer parámetro no es especificado por el código de llamada porque representa el tipo sobre el que el operador está siendo aplicado, y el compilador ya sabe el tipo de objeto que debe de usar. Usted solamente tiene que suministrar valores a partir del segundo parámetro en adelante.
Veamos el siguiente ejemplo:
Vamos a definir un método extendido para la clase System.Int32 (es decir agregar un método al tipo Entero) esté método devolverá el doble del valor que contenga la variable, el método se llamará “DoubleInSize”.
La clase que contiene el método extendido está definida en un nombre de espacio llamado “IntegerExtensions” que luce así:
delphi
namespace IntegerExtensions; interface uses System.Runtime.CompilerServices; type [Extension] IntegerExtensions = public static class public [Extension] class method DoubleInSize (i : integer) : Integer; end; implementation class method IntegerExtensions.DoubleInSize ( i : integer) : Integer; begin Result:= i + i; end; end.
Y el código que consume este método luce de la siguiente manera:
delphi
uses IntegerExtensions; Var i : Integer:=10; MessageBox.Show(i.DoubleInSize.ToString);
Hay que tener en mente ciertas cosas cuando vayamos a usar estos métodos:
1. El número de versión.- El número de versión de estos métodos es completamente independiente de la clase a la que afectan, esto puede provocar efectos no deseados cuando la clase sobre la cual se implementan sufre algún cambio.
2. El nombre del método.- El agregar un método a la clase sobre la cual se aplica el método podría hacer que el método de extensión asociado a la misma y con un nombre similar no se ejecutara, pues el miembro de la instancia siempre tendrá preferencia sobre el método de extensión. El problema es que el compilador no podría avisar de algún problema, y en tiempo de ejecución es donde podrían aparecer las incompatibilidades entre ambos métodos.
3. Especificación de nombres de espacios incorrectos.- No hay forma de impedir que un mismo método de extensión sea definido en dos nombres de espacio diferentes, lo cual hace que el namespace indicado en la cláusula Uses sea el que esté decidiendo el método de extensión a ejecutar.
La imagen muestra que intellisense muestra el método como si fuera parte de la propia clase.