Ayer, a raíz de un post del colega Javier Torrecilla sobre métodos extensores, unos cuantos de nosotros entre los que estaban el propio Javier y Jorge Serrano nos enzarzamos en una discusión en twitter acerca del mejor modo de declarar nuestros métodos extensores.
Pongamos un ejemplo: Supongamos que queremos crear un método extensor para comprobar si un valor está entre dos valores (el clásico between de toda la vida).
Agrego una clase llamada ExtensionMethods a mi proyecto, o a otro proyecto mi solución y agrego este código:
namespace CustomExtensions
{
public static class ExtensionMethods
{
public static bool Between<T>(this T @value, T min, T max) where T : IComparable<T>
{
return @value.CompareTo(min) >= 0 && @value.CompareTo(max) <= 0;
}
}
}
Suponiendo que estamos en un proyecto de tipo WinForms, si queremos utilizar este método extensor sobre un valor de tipo int basta con ir a cualquier formulario y llamar al método between sobre un valor de este tipo. Por ejemplo:
Oops! Que pasa? Por que no aparece el método extensor? Bueno, como ya os habréis dado cuenta el método extensor está declarado dentro de un namespce llamado ‘CustomExtensions’, que es distinto al namespace del formulario en el que lo estoy probando, con lo que no podemos usarlo directamente si previamente no hacemos un using:
using CustomExtensions;
Vale, ahora si que aparece:
Bien. Esto en si no es nada del otro mundo, pero la cuestión es que si deseamos evitar declarar el using (tenéis que pensar que este método extensor lo podéis reutilizar en 1000 proyectos distintos), no tenemos otra opción que:
- Declarar el método extensor en un namespace que se llame igual que el namespace en el que se va a usar.
- Declarar el método extensor en un namespace que se llame igual que el namespace del tipo que estamos extendiendo.
- Pasar de todo y llamarlo al namespace como queramos, y que a la hora de usarlo debamos usar un using para agregarlo.
Particularmente soy partidario del segundo punto, de modo que si vamos a extender elementos de tipo IComparable, en lugar de usar el namespace ‘CustomExtensions’ prefiero usar el nombre del namespace que contiene la definición de este tipo, o sea ‘System’:
namespace System
{
public static class ExtensionMethods
{
public static bool Between<T>(this T @value, T min, T max) where T : IComparable<T>
{
return @value.CompareTo(min) >= 0 && @value.CompareTo(max) <= 0;
}
}
}
Pero ese es mi punto de vista, tu que opinas? Twitteros manifestaos! 🙂