Esta es una pregunta sobre los métodos de extensión de C # y su filosofía de diseño, por lo que creo que la mejor manera de responder a esta pregunta es citar la documentación de MSDN sobre el propósito de los métodos de extensión :
Los métodos de extensión le permiten "agregar" métodos a los tipos existentes sin crear un nuevo tipo derivado, volver a compilar o modificar el tipo original. Los métodos de extensión son un tipo especial de método estático, pero se llaman como si fueran métodos de instancia en el tipo extendido. Para el código de cliente escrito en C #, F # y Visual Basic, no existe una diferencia aparente entre llamar a un método de extensión y los métodos que realmente están definidos en un tipo.
...
En general, le recomendamos que implemente los métodos de extensión con moderación y solo cuando sea necesario. Siempre que sea posible, el código del cliente que debe extender un tipo existente debe hacerlo creando un nuevo tipo derivado del tipo existente. Para obtener más información, vea Herencia.
Cuando utiliza un método de extensión para extender un tipo cuyo código fuente no puede cambiar, corre el riesgo de que un cambio en la implementación del tipo haga que su método de extensión se rompa.
Si implementa métodos de extensión para un tipo dado, recuerde los siguientes puntos:
- Nunca se llamará a un método de extensión si tiene la misma firma que un método definido en el tipo.
- Los métodos de extensión se incorporan al nivel del espacio de nombres. Por ejemplo, si tiene varias clases estáticas que contienen métodos de extensión en un solo espacio de nombres con nombre
Extensions
, la using Extensions;
directiva los incluirá a todos .
Para resumir, los métodos de extensión están diseñados para agregar métodos de instancia a un tipo particular, incluso cuando los desarrolladores no pueden hacerlo directamente. Y debido a que los métodos de instancia siempre anularán los métodos de extensión si están presentes (si se llama utilizando la sintaxis del método de instancia), esto solo debe hacerse si no puede agregar directamente un método o extender la clase. *
En otras palabras, un método de extensión debería actuar exactamente como lo haría un método de instancia, porque puede terminar siendo un método de instancia por algún cliente. Y debido a que un método de instancia debería arrojar si el objeto al que se está llamando es null
, también debería hacerlo el método de extensión.
* Como nota al margen, esta es exactamente la situación que enfrentaron los diseñadores de LINQ: cuando se lanzó C # 3.0, ya había millones de clientes que usaban System.Collections.IEnumerable
y System.Collections.Generic.IEnumerable<T>
, tanto en sus colecciones como en foreach
bucles. Estas clases volvieron IEnumerator
objetos que sólo tenían los dos métodos Current
y MoveNext
, por lo que añadir cualquiera de los métodos instancia necesarios adicionales, tales como Count
, Any
, etc., sería romper estos millones de clientes. Entonces, para proporcionar esta funcionalidad (especialmente porque se puede implementar en términos de Current
y MoveNext
con relativa facilidad), la lanzaron como métodos de extensión, que se pueden aplicar a cualquier sistema existente actualmente.IEnumerable
instancia y también puede ser implementado por clases de maneras más eficientes. Si los diseñadores de C # hubieran decidido lanzar LINQ el primer día, se habrían proporcionado como métodos de instancia IEnumerable
y probablemente habrían diseñado algún tipo de sistema para proporcionar implementaciones de interfaz predeterminadas de esos métodos.