Los métodos de extensión no proporcionan algo que no se puede hacer de otras maneras. Son azúcar sintáctico para hacer que el desarrollo sea más agradable, sin proporcionar un beneficio técnico real.
Los métodos de extensión son relativamente nuevos. Los estándares y las convenciones generalmente se deciden por opinión popular (además de cierta experiencia a largo plazo sobre lo que termina siendo una mala idea), y no creo que estemos en el punto en el que podamos trazar una línea definitiva con la que todos estén de acuerdo.
Sin embargo, puedo ver varios argumentos, basados en las cosas que escuché de mis compañeros de trabajo.
1. Generalmente están reemplazando los métodos estáticos.
Los métodos de extensión se basan más comúnmente en cosas que de otro modo habrían sido métodos estáticos, no métodos de clase. Ellos se ven como métodos de clase, pero no lo son en realidad.
Los métodos de extensión simplemente no deberían considerarse una alternativa para los métodos de clase; sino más bien como una forma de dar a los métodos estáticos de manera sintáctica una apariencia y sensación de "clase de método".
2. Cuando su método previsto es específico para un proyecto consumidor pero no la biblioteca fuente.
El hecho de que desarrolle tanto la biblioteca como el consumidor no significa que esté dispuesto a poner la lógica donde sea que encaje.
Por ejemplo:
- Tienes una
PersonDtoclase proveniente de tu DataLayerproyecto.
- Su
WebUIproyecto quiere poder convertir PersonDtoa a PersonViewModel.
No puede (y no querría) agregar este método de conversión a su DataLayerproyecto. Dado que este método tiene un alcance para el WebUIproyecto, debe vivir dentro de ese proyecto.
Un método de extensión le permite tener este método accesible globalmente dentro de su proyecto (y posibles consumidores de su proyecto), sin requerir que la DataLayerbiblioteca lo implemente.
3. Si cree que las clases de datos solo deben contener datos.
Por ejemplo, su Personclase contiene las propiedades de una persona. Pero desea poder tener algunos métodos que formateen algunos de los datos:
public class Person
{
//The properties...
public SecurityQuestionAnswers GetSecurityAnswers()
{
return new SecurityQuestionAnswers()
{
MothersMaidenName = this.Mother.MaidenName,
FirstPetsName = this.Pets.OrderbyDescending(x => x.Date).FirstOrDefault()?.Name
};
}
}
He visto muchos compañeros de trabajo que odian la idea de mezclar datos y lógica en una clase. No estoy del todo de acuerdo con cosas simples como formatear datos, pero reconozco que en el ejemplo anterior, se siente sucio Persontener que depender SecurityQuestionAnswers.
Al poner este método en un método de extensión, se evita el ensuciamiento de la clase de datos pura.
Tenga en cuenta que este argumento es de estilo. Esto es similar a las clases parciales. Hacerlo tiene poco o ningún beneficio técnico, pero le permite separar el código en varios archivos si lo considera más limpio (por ejemplo, si muchas personas usan la clase pero no se preocupan por sus métodos personalizados adicionales).
4. Métodos auxiliares
En la mayoría de los proyectos, tiendo a terminar con clases de ayuda. Estas son clases estáticas que generalmente proporcionan una colección de métodos para formatear fácilmente.
Por ejemplo, una empresa en la que trabajé tenía un formato de fecha y hora particular que querían usar. En lugar de tener que pegar la cadena de formato en todo el lugar, o hacer que la cadena de formato sea una variable global, opté por un método de extensión DateTime:
public static string ToCompanyFormat(this DateTime dt)
{
return dt.ToString("...");
}
¿Es eso mejor que un método auxiliar estático normal? Creo que sí. Limpia la sintaxis. En vez de
DateTimeHelper.ToCompanyFormat(myObj.CreatedOn);
Yo podría hacer:
myObj.CreatedOn.ToCompanyFormat();
Esto es similar a una versión fluida de la misma sintaxis. Me gusta más, a pesar de que no hay un beneficio técnico de tener uno sobre el otro.
Todos estos argumentos son subjetivos. Ninguno de ellos cubre un caso que de otra manera nunca podría estar cubierto.
- Cada método de extensión puede reescribirse fácilmente en un método estático normal.
- El código se puede separar en archivos usando clases parciales, incluso si los métodos de extensión no existieran.
Pero, de nuevo, podemos tomar su afirmación de que nunca son necesarios al extremo:
- ¿Por qué necesitamos métodos de clase, si siempre podemos hacer métodos estáticos con un nombre que indique claramente que es para una clase en particular?
La respuesta a esta pregunta, y la suya, sigue siendo la misma:
- Mejor sintaxis
- Mayor legibilidad y menos pedantería de código (el código llegará al punto en menos caracteres)
- Intellisense proporciona resultados contextualmente significativos (los métodos de extensión solo se muestran en el tipo correcto. Las clases estáticas se pueden usar en todas partes).
Sin embargo, una mención extra particular:
- Los métodos de extensión permiten un estilo de codificación de encadenamiento de métodos; que se ha vuelto más popular últimamente, a diferencia de la sintaxis de envoltura del método más vainilla. Se pueden ver preferencias sintácticas similares en la sintaxis de métodos de LINQ.
- Si bien el encadenamiento de métodos también se puede hacer usando métodos de clase; tenga en cuenta que esto no se aplica a los métodos estáticos. Los métodos de extensión se basan más comúnmente en cosas que de otro modo habrían sido métodos estáticos, no métodos de clase.