2010-12-18 22 views

Respuesta

9

Los métodos de extensión se especifican poniendo la palabra clave this delante del primer parámetro de un método estático:

public static void SomeExtension(this string s) 
{ 
    ... 
} 

Ese es el azúcar solo sintáctica para decorar el método con System.Runtime.CompilerServices.ExtensionAttribute:

[Extension] 
public static void SomeExtension(string s) 
{ 
    ... 
} 

Cuando el compilador ve ese atributo, sabe traducir la llamada al método de extensión a la llamada al método estático correspondiente, pasando la instancia como el primer parámetro.

Dado que las llamadas son solo llamadas a métodos estáticos normales, no hay posibilidad de romper la encapsulación; los métodos, como todos los métodos estáticos, solo tienen acceso a las interfaces públicas de los tipos extendidos.

+0

1 buen punto :) –

16

No se "conectan".

El IDE de Visaul Studio simplemente lo hace lucir como lo muestra mostrándolo en las listas intellisense.

El compilador "sabe" cómo tratar las referencias para realizar las llamadas a los métodos correctos con los parámetros correctos.

Esto es simplemente syntactic sugar - los métodos son simplemente métodos estáticos en una clase estática separada. El uso del modificador this le permite al compilador "saber" para agregar el ExtensionAttribute a la clase para marcarlo como un método de extensión.

Dado que los métodos de extensión hacen no, de hecho, el cambio la clase y sólo se puede acceder a miembros del público en él, se retiene la encapsulación.

De MSDN:

Los métodos de extensión son un tipo especial de método estático, sino que son llamados como si fueran métodos de instancia en el tipo extendido.

(el énfasis es mío)

4

Los métodos de extensión son el azúcar solo sintáctica, son simplemente métodos estáticos. Solo puede acceder a campos públicos o propiedades en ellos, al igual que los métodos estáticos normales.

2

El ingrediente clave es que un método de instancia de una clase no es fundamentalmente diferente de un método estático. Con un pequeño detalle, tienen un argumento oculto. Por ejemplo, el método String.IndexOf (char) en realidad se parece esto a la CLR:

public static int IndexOf(string thisRef, char value) { 
    // etc... 
} 

El argumento thisRef es lo que suministra la cadena de referencia cada vez que utilice este en el código o acceder a un miembro de la clase. Como puede ver, es un muy pequeño paso de un método de extensión a un método de instancia.No se necesitaban cambios en el CLR para admitir la función.

Otra pequeña diferencia es que el compilador emite código que comprueba si este es nulo para un método de instancia, pero no lo hace para un método de extensión. Puede llamar a un método de extensión en un objeto nulo. Si bien eso podría parecer una característica, en realidad es una restricción inducida por el método de extensión que en realidad no es miembro de la clase.

Internamente, el CLR guarda una lista de métodos para la clase, el MethodTable. Los métodos de extensión no están en ellos, lo que impide que el compilador emita la instrucción callvirt IL, el "truco" que utiliza para obtener la comprobación nula barata. La emisión explícita de código para hacer la verificación nula hubiera sido posible, pero eligieron no hacerlo. No estoy seguro por qué.

Otra consecuencia automática de esto es que un método de extensión no puede ser virtual.

Cuestiones relacionadas