¿Qué ventajas de los métodos de extensión ha encontrado? [cerrado]


84

Un "no creyente" de C # me preguntaba cuál era el propósito de los métodos de extensión. Le expliqué que luego podría agregar nuevos métodos a los objetos que ya estaban definidos, especialmente cuando no posee / controla la fuente del objeto original.

Él mencionó "¿Por qué no agregar un método a su propia clase?" Hemos estado dando vueltas y vueltas (en el buen sentido). Mi respuesta general es que es otra herramienta en el cinturón de herramientas, y su respuesta es que es un desperdicio inútil de una herramienta ... pero pensé que obtendría una respuesta más "ilustrada".

¿Cuáles son algunos de los escenarios en los que ha utilizado métodos de extensión que no podría (o no debería) haber utilizado un método agregado a su propia clase?


2
Creo que definitivamente hay puntos válidos que la gente puede hacer (y ha hecho) en apoyo de los métodos de extensión ... pero definitivamente no hay un escenario en el que uno " no podría haber usado" métodos estáticos en lugar de métodos de extensión. Los métodos de extensión en realidad son solo métodos estáticos, a los que se accede de una manera diferente. Sólo algo para tener en cuenta.
Dan Tao

@DanTao, en una nota más ligera, lo único que hace que las llamadas por método de extensión sean insustituibles son sus propios nombres. Extensions.To(1, 10)no tiene sentido y 1.To(10)es descriptivo. Por supuesto que entiendo el aspecto técnico del que estás hablando, simplemente diciendo. De hecho, hay escenarios en los que uno " no podría haber" utilizado un enfoque de extensión en lugar de métodos estáticos, la reflexión, por ejemplo, otro caso es dynamic.
nawfal

Respuestas:


35

Creo que los métodos de extensión ayudan mucho al escribir código; si agrega métodos de extensión a los tipos básicos, los obtendrá rápidamente en intellisense.

Tengo un proveedor de formato para formatear un tamaño de archivo . Para usarlo necesito escribir:

Console.WriteLine(String.Format(new FileSizeFormatProvider(), "{0:fs}", fileSize));

Creando un método de extensión puedo escribir:

Console.WriteLine(fileSize.ToFileSize());

Más limpio y sencillo.


4
un nombre más descriptivo para su método de extensión lo haría aún más limpio. por ejemplo, fileSize.ToFormattedString ();
David Alpert

1
mmm, ToFormattedFizeSize () tal vez, es un método de extensión para un tipo Long, ToFormattedString () no es un nombre descriptivo
Eduardo Campañó

3
punto hecho, sin embargo. cuando leo fileSize.ToFileSize () pregunto por qué la duplicación? ¿Qué está haciendo realmente? Sé que es solo un ejemplo, pero los nombres descriptivos ayudan a hacerlo limpio y simple.
David Alpert

1
tienes razón porque en las pruebas es muy importante elegir el nombre correcto
Eduardo Campañó

5
Sin embargo, esto no responde a la pregunta directamente, ya que el ejemplo que proporcionó no necesita ser un método de extensión. Podrías haberlo hecho LongToFileSize(fileSize), lo cual es igual de conciso y posiblemente igual de claro.
Dan Tao

83

El único ventaja de los métodos de extensión es la legibilidad del código. Eso es.

Los métodos de extensión le permiten hacer esto:

foo.bar();

en lugar de esto:

Util.bar(foo);

Ahora hay muchas cosas en C # que son así. En otras palabras, hay muchas características en C # que parecen triviales y no tienen un gran beneficio en sí mismas. Sin embargo, una vez que comienzas a combinar estas características, comienzas a ver algo un poco más grande que la suma de sus partes. LINQ se beneficia enormemente de los métodos de extensión, ya que las consultas LINQ serían casi ilegibles sin ellos. LINQ sería posible sin métodos de extensión, pero no es práctico.

Los métodos de extensión se parecen mucho a las clases parciales de C #. Por sí mismos no son muy útiles y parecen triviales. Pero cuando empiezas a trabajar con una clase que necesita código generado, las clases parciales empiezan a tener mucho más sentido.


1
Esto se vuelve aún más importante si está utilizando métodos encadenados como x.Foo (algo) .Bar (algo) .Baz (todavía algo). Esto es más frecuente en los métodos de extensión IEnumerable <> y aumenta significativamente la legibilidad
ShuggyCoUk

2
Lo que no entiendo es que foo.bar () me sugiere que bar () es un método de foo. Entonces, cuando no funciona, termino buscando en el lugar equivocado. No estoy seguro de que esto sea realmente una mejora de legibilidad para mí.
Martin Brown

3
Hacer clic con el botón derecho en la barra () en VS IDE y elegir Ir a la Definición lo llevará al lugar correcto.
Jeff Martin

9
La única ventaja del 98% de las construcciones del lenguaje es la legibilidad del código. Cualquier cosa más allá de un operador de sucursal, etiqueta, goto e incremento está ahí para hacerle la vida un poco más fácil.
Giovanni Galbo

2
Eso no es del todo cierto, hay algunas situaciones en las que los métodos de extensión son la única forma de extender una clase. Además de las clases selladas, las uso en una situación bastante única. Vea mi publicación a continuación.
Edwin Jarvis

34

¡No olvide las herramientas! Cuando agrega un método de extensión M en el tipo Foo, obtiene 'M' en la lista intellisense de Foo (asumiendo que la clase de extensión está dentro del alcance). Esto hace que 'M' sea mucho más fácil de encontrar que MyClass.M (Foo, ...).

Al final del día, es solo azúcar sintáctico para otros métodos estáticos, pero como comprar una casa: '¡ubicación, ubicación, ubicación!' Si se cuelga del tipo, la gente lo encontrará.


2
También hay un pequeño inconveniente en esto: los métodos de extensión (como los de System.Linq completan el autocompletado de IntelliSense con una lista más larga, lo que hace que sea un poco más difícil de navegar.)
Jared Updike

@Jared: ... pero solo si ha importado el espacio de nombres donde residen los métodos de extensión, por lo que en realidad tiene un pequeño grado de control sobre esta "contaminación IntelliSense". En segundo lugar, no olvidemos que hay clases en el BCL (como String) que vienen con una lista bastante larga de métodos de instancia, por lo que este problema no es específico de los métodos de extensión.
stakx - ya no contribuye el

29

Dos beneficios más de los métodos de extensión con los que me he encontrado:

  • Una interfaz fluida se puede encapsular en una clase estática de métodos de extensión, logrando así una separación de preocupaciones entre la clase principal y sus extensiones fluidas; He visto que logran una mayor capacidad de mantenimiento.
  • Los métodos de extensión se pueden colgar de las interfaces, lo que le permite especificar un contrato (a través de una interfaz) y una serie asociada de comportamientos basados ​​en la interfaz (a través de métodos de extensión), ofreciendo nuevamente una separación de preocupaciones. Un ejemplo son la extensión Linq métodos como Select(...), Where(...), etc. Hung fuera de la IEnumerable<T>interfaz.

1
¿Puede citar algunos ejemplos de código para ambos puntos para ayudarlos a comprender mejor? Parece ser un punto de vista interesante.
RBT

sí, un ejemplo para el segundo punto estaría bien.
Ini

26

Algunos de los mejores usos que tuve para los métodos de extensión es la capacidad de:

  1. Ampliar la funcionalidad en objetos de terceros (ya sean comerciales o internos de mi empresa pero gestionados por un grupo separado), que en muchos casos se marcarán como sealed.
  2. Cree una funcionalidad predeterminada para interfaces sin tener que implementar una clase abstracta

Tomemos, por ejemplo IEnumerable<T>,. Si bien es rico en métodos de extensión, me pareció molesto que no implementara un método ForEach genérico. Entonces, hice el mío:

public void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
{
    foreach ( var o in enumerable )
    {
        action(o);
    }
}

Voila, todos mis IEnumerable<T>objetos independientemente del tipo de implementación, y si lo escribí o no, o si alguien más ahora tenía un ForEachmétodo agregando una declaración de "uso" apropiada en mi código.


3
+1 Me encanta esta extensión, escribí una igual. Muy útil
Maslow

10
Tenga en cuenta que el método debe ser estático. Sugiero leer blogs.msdn.com/ericlippert/archive/2009/05/18/… antes de decidirse a utilizar esta extensión.
TrueWill

Razón por la que no se agradece implementar el método de extensión ForEach en IEnumerable - blogs.msdn.microsoft.com/ericlippert/2009/05/18/…
RBT

12

Una de las grandes razones para utilizar métodos de extensión es LINQ. Sin métodos de extensión, mucho de lo que puede hacer en LINQ sería muy difícil. Los métodos de extensión Where (), Contains (), Select significan que se agrega mucha más funcionalidad a los tipos existentes sin cambiar su estructura.


4
no es "uno de", es LA razón de los métodos de extensión.
gbjbaanb

3
¿Cómo es eso? Es una de las muchas razones para tener métodos de extensión, no el único requisito. Puedo usar métodos de extensión sin usar LINQ.
Ray Booysen

Creo que quiso decir que fue la razón por la que fueron creados, pero sí, hace que parezca que son el único uso adecuado para ellos.
Brent Rittenhouse

9

Hay muchas respuestas sobre el ventajas de los métodos de extensión; ¿ Qué tal uno que aborde las desventajas ?

La mayor desventaja es que no hay ningún error o advertencia del compilador si tiene un método regular y un método de extensión con la misma firma en el mismo contexto.

Suponga que crea un método de extensión que se aplica a una clase en particular. Luego, más tarde, alguien crea un método con una firma idéntica en esa clase.

Su código se compilará y es posible que ni siquiera obtenga un error de tiempo de ejecución. Pero ya no está ejecutando el mismo código que antes.


1
4. Piense dos veces antes de extender los tipos que no posee . Si solo escribe métodos de extensión para los tipos que posee, nunca tendrá que preocuparse de que sus extensiones se rompan debido a cambios en el tipo que se está extendiendo. Por otro lado, si está extendiendo otros tipos de personas, está esencialmente a su merced.
DavidRR

1
... Alternativamente, puede minimizar este riesgo eligiendo nombres que probablemente no sean utilizados por otra persona, o minimizando el número total de métodos de extensión que defina (es decir, reduciendo el área de superficie). Una técnica para hacer esto puede ser escribir un método de extensión que convierta el objeto subyacente en un tipo diferente controlado por usted.
DavidRR

Métodos de extensión (Guía de programación de C #) : en general, probablemente llamará a métodos de extensión con mucha más frecuencia que implementando los suyos propios.
DavidRR


4

Mi argumento personal para los métodos de extensión es que encajan muy bien en un diseño de programación orientada a objetos: considere el método simple

bool empty = String.IsNullOrEmpty (myString)

en comparación con

bool empty = myString.IsNullOrEmpty ();

No veo qué tiene que ver tu ejemplo con OOP. ¿Qué quieres decir?
Andrew Hare

1
"parece" que el método pertenece al objeto
Bluenuance

3
Este es un mal ejemplo (puede lanzar NullReferenceException) pero está en el camino correcto. Un mejor ejemplo podría ser reemplazar Math.abs (-4) con algo como -4.abs ();
Programador fuera de la ley

15
que yo sepa (y mi experiencia, si la memoria no funciona), myString.IsNullOrEmpty () no necesita lanzar una NullReferenceException porque los métodos de extensión no requieren una instancia de objeto para dispararse.
David Alpert

1
Personalmente, no soy un fanático de los métodos de extensión que están destinados a funcionar con una instancia nula; al lector le parece una cosa, pero luego hace otra.
Mark Simpson

4

Hay un montón de excelentes respuestas arriba sobre lo que los métodos de extensión le permiten hacer.

Mi respuesta corta es: casi eliminan la necesidad de fábricas.

Solo señalaré que no son un concepto nuevo y una de las mayores validaciones de ellos es que son una característica excelente en Objective-C ( categorías ). Añaden tanta flexibilidad al desarrollo basado en marcos que NeXT tenía a los modeladores financieros de la NSA y Wall Street como principales usuarios.

REALbasic también los implementa como métodos extendidos y han sido de uso similar allí simplificando el desarrollo.


4

Me gustaría apoyar las otras respuestas aquí que mencionan la legibilidad mejorada del código como una razón importante detrás de los métodos de extensión. Demostraré esto con dos aspectos de esto: encadenamiento de métodos frente a llamadas a métodos anidados y desorden de una consulta LINQ con nombres de clases estáticas sin sentido.


Tomemos esta consulta LINQ como ejemplo:

numbers.Where(x => x > 0).Select(x => -x)

Ambos Wherey Selectson métodos de extensión, definidos en la clase estática Enumerable. Por lo tanto, si los métodos de extensión no existieran, y estos fueran métodos estáticos normales, la última línea de código esencialmente tendría que verse así:

Enumerable.Select(Enumerable.Where(numbers, x => x > 0), x => -x)

Vea cuánto más desagradable se acaba de hacer esa consulta.


En segundo lugar, si ahora quisiera introducir su propio operador de consulta, naturalmente no tendría forma de definirlo dentro de la Enumerableclase estática, como todos los demás operadores de consulta estándar, porque Enumerableestá en el marco y no tiene control sobre esa clase. Por lo tanto, tendría que definir su propia clase estática que contenga métodos de extensión. A continuación, puede recibir consultas como esta:

Enumerable.Select(MyEnumerableExtensions.RemoveNegativeNumbers(numbers), x => -x)
//                ^^^^^^^^^^^^^^^^^^^^^^
//                different class name that has zero informational value
//                and, as with 'Enumerable.xxxxxx', only obstructs the
//                query's actual meaning.

3

Es cierto que puede agregar su método (extensión) directamente a su clase. Pero no todas las clases están escritas por ti. Las clases de la biblioteca central o de las bibliotecas de terceros a menudo están cerradas y sería imposible obtener el azúcar sintético sin métodos de extensión. Pero recuerde, los métodos de extensión son como los métodos independientes (estáticos) en eg. c ++


3

Los métodos de extensión también pueden ayudar a mantener limpias las clases y las dependencias de clases. Por ejemplo, es posible que necesite un método Bar () para la clase Foo en todos los lugares donde se use Foo. Sin embargo, es posible que desee un método .ToXml () en otro ensamblado y solo para ese ensamblado. En ese caso, puede agregar las dependencias System.Xml y / o System.Xml.Linq necesarias en ese ensamblado y no en el ensamblado original.

Beneficios: las dependencias en su ensamblado de clase de definición se reducen solo a las necesidades básicas y se evitará que otros ensamblados consumidores utilicen el método ToXml (). Consulte esta presentación de PDC para obtener más información.


3

Estoy de acuerdo en que los métodos de extensión aumentan la legibilidad del código, pero en realidad no son más que métodos auxiliares estáticos.

En mi opinión, el uso de métodos de extensión para agregar comportamiento a sus clases puede ser:

Confuso: los programadores pueden creer que los métodos son parte del tipo extendido, por lo que no comprenden por qué los métodos desaparecen cuando el espacio de nombres de extensión no se importa.

Un antipatrón: decide agregar comportamiento a los tipos en su marco utilizando métodos de extensión, luego enviándolos a alguna persona para que los realice pruebas unitarias. Ahora está atrapado con un marco que contiene un montón de métodos que no puede falsificar.


No es cierto que un desarrollador esté atascado con un montón de métodos que no puede falsificar. Estos métodos de extensión eventualmente llaman a algún método en la clase / interfaz que están extendiendo y este método puede ser interceptado dado que es virtual.
Patrik Hägne

1
Bueno, entonces depende de lo que se haga en el método de extensión. Digamos que usa los métodos de extensión proporcionados en una interfaz, sin siquiera saber que son métodos de extensión. Entonces no querrá simular una llamada a un método a una interfaz, pero se dará cuenta de que en realidad está invocando un método estático. Una llamada a un método estático no puede ser interceptada por una API de falsificación basada en proxy, por lo que su única opción es hacer una reflexión sobre el método de extensión para averiguar qué métodos falsificar realmente. Sigue siendo antipattern cuando se combina con pruebas unitarias en mi opinión.
HaraldV

2

Los métodos de extensión son realmente la incorporación .NET de la refactor "Introducir método extranjero" del Libro de Martin Fowler (hasta la firma del método). Vienen con básicamente los mismos beneficios y trampas. En la sección sobre este refactor, dice que son una solución para cuando no puede modificar la clase que realmente debería poseer el método.


2
+1, pero tenga en cuenta que también puede usar métodos de extensión con interfaces.
TrueWill

2

Principalmente veo los métodos de extensión como una admisión de que quizás no deberían haber rechazado las funciones gratuitas.

En la comunidad de C ++, a menudo se considera una buena práctica de programación orientada a objetos preferir funciones de no miembros libres sobre miembros, porque estas funciones no rompen la encapsulación al obtener acceso a miembros privados que no necesitan. Los métodos de extensión parecen ser una forma indirecta de lograr lo mismo. Es decir, una sintaxis más limpia para funciones estáticas que no tienen acceso a miembros privados.

Los métodos de extensión no son más que azúcar sintáctico, pero no veo ningún daño en su uso.


2
  • Intellisense en el objeto mismo en lugar de tener que llamar a alguna función de utilidad fea
  • Para las funciones de conversión, puede cambiar "XToY (X x)" a "ToY (este X x)", lo que da como resultado un bonito x.ToY () en lugar de un feo XToY (x).
  • Amplíe las clases sobre las que no tiene control
  • Extienda la funcionalidad de las clases cuando no sea deseable agregar métodos a las clases mismas. Por ejemplo, puede mantener los objetos comerciales simples y libres de lógica, y agregar lógica comercial específica con dependencias desagradables en los métodos de extensión.

2

Los uso para reutilizar mis clases de modelo de objetos. Tengo un montón de clases que representan objetos que tengo en una base de datos. Estas clases se utilizan en el lado del cliente solo para mostrar los objetos, por lo que el uso básico es acceder a las propiedades.

public class Stock {
   public Code { get; private set; }
   public Name { get; private set; }
}

Debido a ese patrón de uso, no quiero tener métodos de lógica empresarial en estas clases, por lo que hago que cada lógica empresarial sea un método de extensión.

public static class StockExtender {
    public static List <Quote> GetQuotesByDate(this Stock s, DateTime date)
    {...}
}

De esta manera, puedo usar las mismas clases para el procesamiento de la lógica empresarial y para la visualización de la interfaz de usuario sin sobrecargar el lado del cliente con código innecesario.

Una cosa interesante acerca de esta solución es que mis clases de modelo de objetos se generan dinámicamente usando Mono.Cecil , por lo que sería muy difícil agregar métodos de lógica empresarial incluso si quisiera. Tengo un compilador que lee archivos de definición XML y genera estas clases stubs que representan algún objeto que tengo en la base de datos. El único enfoque en este caso es ampliarlos.


1
Podrías usar clases parciales para esto ...
JJoos


1

En mi último proyecto, utilicé el método de extensión para adjuntar métodos Validate () a objetos comerciales. Justifiqué esto porque los objetos comerciales eran objetos de transferencia de datos serializables y se usarán en diferentes dominios, ya que eran entidades de comercio electrónico generales como producto, cliente, comerciante, etc.Bueno, en diferentes dominios las reglas comerciales también pueden ser diferentes, así que encapsulé mi Lógica de validación de enlace tardío en un método de validación adjunto a la clase base de mis objetos de transferencia de datos. Espero que esto tenga sentido :)


1

Un caso en el que los métodos de extensión fueron bastante útiles fue en una aplicación cliente que usa servicios web ASMX. Debido a la serialización, los tipos de retorno de métodos web no contienen ningún método (solo las propiedades públicas de estos tipos están disponibles en el cliente).

Los métodos de extensión permitieron su uso para agregar funcionalidad (en el lado del cliente) a los tipos devueltos por los métodos web sin tener que crear otro modelo de objeto o numerosas clases contenedoras en el lado del cliente.


1

Los métodos de extensión se pueden utilizar para crear una especie de mezcla en C #.

Esto, a su vez, proporciona una mejor separación de las preocupaciones por los conceptos ortogonales. Eche un vistazo a esta respuesta como ejemplo.

Esto también se puede usar para habilitar roles en C #, un concepto fundamental para la arquitectura DCI .


1

También recuerde que los métodos de extensión se agregaron como una forma de ayudar a que las consultas de Linq sean más legibles cuando se usan en su estilo C #.

Estas 2 afectaciones son absolutamente equivalentes, pero la primera es mucho más legible (y la brecha en la legibilidad, por supuesto, aumentaría con más métodos encadenados).

int n1 = new List<int> {1,2,3}.Where(i => i % 2 != 0).Last();

int n2 = Enumerable.Last(Enumerable.Where(new List<int> {1,2,3}, i => i % 2 != 0));

Tenga en cuenta que la sintaxis completa debería ser incluso:

int n1 = new List<int> {1,2,3}.Where<int>(i => i % 2 != 0).Last<int>();

int n2 = Enumerable.Last<int>(Enumerable.Where<int>(new List<int> {1,2,3}, i => i % 2 != 0));

Por casualidad, los parámetros de tipo de Wherey Lastno necesitan ser mencionados explícitamente ya que se pueden inferir gracias a la presencia del primer parámetro de estos dos métodos (el parámetro que es introducido por la palabra clavethis y los convierte en métodos de extensión).

Este punto es obviamente una ventaja (entre otras) de los métodos de extensión, y puede beneficiarse de él en todos los escenarios similares en los que esté involucrado el encadenamiento de métodos.

Especialmente, es la forma más elegante y convincente que encontré de tener un método de clase base invocable por cualquier subclase y devolver una referencia fuertemente tipada a esta subclase (con el tipo de subclase).

Ejemplo (ok, este escenario es totalmente cursi): después de una buena noche, un animal abre los ojos y luego da un grito; todos los animales abren los ojos de la misma manera, mientras que un perro ladra y un pato kwak.

public abstract class Animal
{
    //some code common to all animals
}

public static class AnimalExtension
{
    public static TAnimal OpenTheEyes<TAnimal>(this TAnimal animal) where TAnimal : Animal
    {
        //Some code to flutter one's eyelashes and then open wide
        return animal; //returning a self reference to allow method chaining
    }
}

public class Dog : Animal
{
    public void Bark() { /* ... */ }
}

public class Duck : Animal
{
    public void Kwak() { /* ... */ }
}

class Program
{
    static void Main(string[] args)
    {
        Dog Goofy = new Dog();
        Duck Donald = new Duck();
        Goofy.OpenTheEyes().Bark(); //*1
        Donald.OpenTheEyes().Kwak(); //*2
    }
}

Conceptualmente OpenTheEyesdebería ser un Animalmétodo, pero luego devolvería una instancia de la clase abstracta Animal, que no conoce métodos de subclase específicos comoBark o Ducklo que sea. Las 2 líneas comentadas como * 1 y * 2 generarían un error de compilación.

Pero gracias a los métodos de extensión, podemos tener una especie de "método base que conoce el tipo de subclase en el que se llama".

Tenga en cuenta que un método genérico simple podría haber hecho el trabajo, pero de una manera mucho más incómoda:

public abstract class Animal
{
    //some code common to all animals

    public TAnimal OpenTheEyes<TAnimal>() where TAnimal : Animal
    {
        //Some code to flutter one's eyelashes and then open wide
        return (TAnimal)this; //returning a self reference to allow method chaining
    }
}

Esta vez, no hay parámetro y, por lo tanto, no es posible inferencia del tipo de retorno. La llamada no puede ser otra que:

Goofy.OpenTheEyes<Dog>().Bark();
Donald.OpenTheEyes<Duck>().Kwak();

... lo que puede pesar mucho el código si se involucra más encadenamiento (especialmente sabiendo que el parámetro de tipo siempre estará <Dog>en la línea de Goofy y <Duck>en la de Donald ...)


1
Primera vez que veo "kwak". ¿Es esta una ortografía común en otro país? La única forma en que lo he visto escrito es "charlatán".
Brent Rittenhouse

0

Solo tengo una palabra que decir al respecto: MANTENIMIENTO esta es la clave para el uso de métodos de extensión


4
Creo que es posible que necesite más de una palabra porque no entiendo lo que esto significa.
Programador fuera de la ley

2
De hecho, diría que es un argumento en contra de los métodos de extensión. Uno de los riesgos de los métodos de extensión es que pueden estar en todas partes, creados por todos. El crecimiento salvaje puede ocurrir si no se usa con cuidado.
Boris Callens

Puede encontrar todas las referencias fácilmente cuando utiliza EM. Además, para cambiar globalmente un método, puede hacerlo desde un solo lugar
Tamir

0

Creo que los métodos de extensión ayudan a escribir un código más claro.

En lugar de poner un nuevo método dentro de su clase, como sugirió su amigo, póngalo en el espacio de nombres ExtensionMethods. De esta manera mantendrá un sentido lógico de orden en su clase. Los métodos que realmente no tratan directamente con su clase no la abarrotarán.

Siento que los métodos de extensión hacen que su código sea más claro y organizado de manera más apropiada.


0

Permite que su editor / IDE realice sugerencias de autocompletado de manera inteligente.


0

Me encantan por construir html. Con frecuencia, hay secciones que se utilizan repetidamente o se generan de forma recursiva en las que una función es útil pero de otra manera interrumpiría el flujo del programa.

        HTML_Out.Append("<ul>");
        foreach (var i in items)
            if (i.Description != "")
            {
                HTML_Out.Append("<li>")
                    .AppendAnchor(new string[]{ urlRoot, i.Description_Norm }, i.Description)
                    .Append("<div>")
                    .AppendImage(iconDir, i.Icon, i.Description)
                    .Append(i.Categories.ToHTML(i.Description_Norm, urlRoot)).Append("</div></li>");
            }

        return HTML_Out.Append("</ul>").ToString();

También hay situaciones en las que un objeto necesita lógica personalizada para estar preparado para la salida HTML; los métodos de extensión le permiten agregar esta funcionalidad sin mezclar presentación y lógica dentro de la clase.


0

Descubrí que los métodos de extensión son útiles para hacer coincidir argumentos genéricos anidados.

Eso suena un poco extraño, pero digamos que tenemos una clase genérica MyGenericClass<TList>y sabemos que TList en sí es genérico (por ejemplo, unList<T> ), no creo que haya una manera de extraer esa 'T' anidada de la Lista sin ninguna extensión métodos o métodos auxiliares estáticos. Si solo tenemos métodos auxiliares estáticos a nuestra disposición, es (a) feo y (b) nos obligará a mover la funcionalidad que pertenece a la clase a una ubicación externa.

por ejemplo, para recuperar los tipos en una tupla y convertirlos en una firma de método, podemos usar métodos de extensión:

public class Tuple { }
public class Tuple<T0> : Tuple { }
public class Tuple<T0, T1> : Tuple<T0> { }

public class Caller<TTuple> where TTuple : Tuple { /* ... */ }

public static class CallerExtensions
{
     public static void Call<T0>(this Caller<Tuple<T0>> caller, T0 p0) { /* ... */ }

     public static void Call<T0, T1>(this Caller<Tuple<T0, T1>> caller, T0 p0, T1 p1) { /* ... */ }
}

new Caller<Tuple<int>>().Call(10);
new Caller<Tuple<string, int>>().Call("Hello", 10);

Dicho esto, no estoy seguro de dónde debería estar la línea divisoria: ¿cuándo debería ser un método un método de extensión y cuándo debería ser un método auxiliar estático? ¿Alguna idea?


0

Tengo zonas de entrada en mi pantalla y todas deben implementar un comportamiento estándar, sean cuales sean sus tipos exactos (cuadros de texto, casillas de verificación, etc.). No pueden heredar una clase base común ya que cada tipo de zona de entrada ya deriva de una clase específica (TextInputBox, etc.)

Tal vez al subir en la jerarquía de herencia podría encontrar un ancestro común como, por ejemplo, WebControl, pero no desarrollé la clase de marco WebControl y no expone lo que necesito.

Con el método de extensión, puedo:

1) ampliar la clase WebControl y luego obtener mi comportamiento estándar unificado en todas mis clases de entrada

2) alternativamente, hacer que todas mis clases se deriven de una interfaz, digamos IInputZone, y extender esta interfaz con métodos. Ahora podré llamar a métodos de extensiones relacionados con la interfaz en todas mis zonas de entrada. Por lo tanto, logré una especie de herencia múltiple, ya que mis zonas de entrada ya derivaban de múltiples clases base.


0

Hay tantos ejemplos excelentes de métodos de extensión ... especialmente en IEnumerables como se publicó anteriormente.

por ejemplo, si tengo un IEnumerable<myObject>método de puedo crear y extensión paraIEnumerable<myObject>

mylist List<myObject>;

... crea la lista

mylist.DisplayInMyWay();

Sin los métodos de extensión tendrían que llamar a:

myDisplayMethod(myOldArray); // can create more nexted brackets.

¡Otro gran ejemplo es la creación de una lista enlazada circular en un instante!

¡Puedo tomarme el crédito por ello!

lista enlazada circular usando métodos de extensión

Ahora combine estos y el código de Métodos de extensión se lee como sigue.

myNode.NextOrFirst().DisplayInMyWay();

más bien que

DisplayInMyWay(NextOrFirst(myNode)).

usando métodos de extensión Es más ordenado y más fácil de leer y más orientado a objetos. también muy cerca de:

myNode.Next.DoSomething()

¡Muéstrale eso a tu colega! :)

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.