2010-07-06 14 views
8

Antes de comenzar a señalarme duplicados, solo sé que he leído casi todas las publicaciones en SO sobre los métodos de extensión. Solo estoy tratando de hacer de abogado del diablo por un minuto para considerar la alternativa a mi opinión laboral.¿Cuándo deberían evitarse los métodos de extensión?

Recientemente estaba trabajando en un proyecto y surgió la necesidad de que un método sea la base de una interfaz. Así que sugerí que escribiéramos un método de extensión y fue derribado. Diciéndolo agrega complejidad y es más difícil de depurar.

Por supuesto discutí y en SO para encontrar todas las publicaciones maravillosas que muestran las muchas razones por las que utilizar los métodos de extensión. No hay que olvidar que una gran parte del framework .net los usa. Eventualmente no lo usamos ya que el equipo lo invalidó.

Pero luego me puse a pensar, ¿hay momentos en que un método de extensión podría utilizarse pero no debería ser?

Realmente no pude pensar en ninguno, pero pensé que podría publicar aquí y ver si alguien podría pensar en alguna otra razón por la que no deberían ser utilizados.

+0

ver este artículo ... http://www.vitalygorn.com/blog/post/2008/01/Extension-Methods---Extension-or-Confusion.aspx – Luiscencio

+0

@Luiscencio Gracias por el artículo. Es un poco largo, así que lo leeré en unos minutos y lo publicaré nuevamente. Pero parece que es lo que me preguntaba. – spinon

Respuesta

5

Cada vez que tiene una función que es "generalmente aplicable" a un objeto de un tipo determinado, independientemente de su estado, un método de extensión es una buena opción.

Por ejemplo, hoy he añadido dos nuevos métodos de extensión a nuestra base de código:

public static XElement ToXElement(this XmlElement element) { } 

public static XmlElement ToXmlElement(this XElement element) { } 

Ambos son, en términos generales, válidos en los tipos que se extienden sin importar el estado de la instancia o en los que estamos usándolo

Si su método no cumple con ese criterio, probablemente debería moverse a un método auxiliar más cercano al contexto donde el caso particular siempre es verdadero o fácil de verificar.

Por ejemplo, un desarrollador recientemente nominado que esto sea un método de extensión:

public static bool ParseYesNoBool(this string input) { } 

Hay dos problemas: en primer lugar, este aparecerá en todas las cadenas en la aplicación, a pesar de que el número de cadenas que Quizás alguna vez los candidatos para este caso sean muy pequeños. Así que hemos roto la primera regla, ya que no es útil independientemente del estado. De forma similar, pero en segundo lugar, el consumidor de esta funcionalidad está limitado a un único analizador para un conector en particular a un sistema externo. Por lo tanto, no tiene sentido promocionar la funcionalidad específica de la implementación en el espacio de nombres de uso general. Esto fue degradado a un método auxiliar en el analizador.

En cuanto a la legibilidad y la depuración, eso es incorrecto para un desarrollador de cualquier nivel de habilidad razonable.

+0

Trabajé con alguien que tenía un gran archivo de extensión solo por objeto, la mayoría siendo bastante específico. Casi tuve que empezar a tomar clases de manejo de la ira ... – ChaosPandion

+0

@anon ¿por qué el DV? –

+0

Estos son dos excelentes ejemplos de cuándo deberían y no deberían usarse. He visto situaciones similares donde la funcionalidad específica del objeto se agregó a los objetos clr. Estaban buscando reglas específicas del objeto de dominio en el tipo y deseaban simplemente agregar métodos de extensión al tipo para hacerlo más fácil. Creo que tengo otra pregunta para SO que voy a publicar en lugar de tratar de encajar todo en este comentario? Además, haz que se pueda buscar para futuras referencias. – spinon

0

Diría que debe evitarlos cuando "no hacen que la intención del código sea más clara". Por supuesto, si un código (o un estilo de codificación) es "más claro" y varía mucho entre las personas, entonces eso es bastante inútil. (Tuve un jefe que dijo que deberíamos evitar el uso de interfaces porque hicieron el código "demasiado complejo y difícil de entender")

+0

Me pregunto cómo podrías tener una situación donde podría ser malo. Supongo que si estuvieras poniendo métodos que no tenían nada que ver con la clase o la interfaz, como un método de extensión sería una de esas situaciones. p.s. Tu jefe suena como un maestro OOP real: P – spinon

1

En general, si controla el código fuente para el ensamblaje y agrega el método no causa ningún rompiendo los cambios en el código existente (que hubiera sido el caso si, por ejemplo, LINQ no se hubiera implementado a través de métodos de extensión), es mejor agregar un método normal.

1

This discussion de la sección Diseño de frameworks de Guildelines sobre métodos de extensión contiene algunos buenos consejos. Creo que la parte relevante para su escenario es:

Proporcionar funcionalidad de ayuda relevante para cada implementación de una interfaz, si dicha funcionalidad se puede escribir en términos de la interfaz del núcleo.

Si su uso propuesto no pasó esa prueba, entonces debería haber sido derribado.

+0

Veré si puedo desenterrar el escenario y publicar una explicación modificada aquí. – spinon

0

Los métodos de extensión le permiten "agregar" métodos a tipos existentes sin crear un nuevo tipo derivado, volver a compilar o modificar el tipo original.

Cada vez que rompa la intención y el diseño de la función, le recomiendo que reconsidere el uso de un método de extensión. Veo algunas situaciones en las que no desea utilizar un método de extensión:

1) Cambio del modelo de objetos para permitir un método de extensión: La clase en la que desea crear una extensión es una clase abstracta. Esto requerirá que hagas de cada clase heredada su propia versión de la extensión o elimines el resumen de la clase. De cualquier forma, está cambiando el modelo de objetos para usar un método de extensión.

2) Olvidando el Decorator Pattern: El número de métodos de extensión que crea para una clase excede tres. Encuentro que es más fácil organizar/comunicar y mantener el modelo de dominio/objeto con objetos decorados que con objetos extendidos. Sin embargo, lo opuesto también es cierto: si un objeto decorado tiene menos de cuatro métodos, encuentro muchos objetos casi "vacíos" en mi proyecto.

3) Funciones privadas: Las funciones privadas están destinadas a modificar (crear, eliminar, etc.) el objeto y los métodos de extensión están destinados a usar el tipo, al igual que una estructura. Si encuentra que la extensión se está asignando a otra instancia del tipo, probablemente no debería estar en una extensión.

Cuestiones relacionadas