Tenía curiosidad por saber cómo los métodos de extensión están conectados a la clase Original. Sé que en el código IL da una llamada al Método estático, pero cómo lo hace y por qué no rompe la encapsulación.Cómo se conectan los métodos de extensión
Respuesta
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.
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)
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.
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.
creo que deberías echar un vistazo a http://go.microsoft.com/fwlink/?LinkId=112388
- 1. ¿Cómo se compilan los métodos de extensión?
- 2. ¿Los métodos LINQ son métodos de extensión?
- 3. Reemplazando los métodos de extensión
- 4. ¿Cómo agrupar los métodos de extensión?
- 5. ¿Los métodos de extensión ocultan las dependencias?
- 6. ¿Cuándo deberían evitarse los métodos de extensión?
- 7. ¿Qué son los métodos de extensión?
- 8. ¿Cómo extiendo una clase con los métodos de extensión C#?
- 9. ¿Métodos de extensión virtual?
- 10. ¿Cómo puedo encontrar todos los métodos de extensión en solución?
- 11. Organización de métodos de extensión
- 12. métodos de extensión estáticas
- 13. equivalente de Scala de los métodos de extensión de C#?
- 14. múltiples cláusulas WHERE con los métodos de extensión de LINQ
- 15. Métodos oficiales de extensión LINQ
- 16. Métodos de extensión de enumeración
- 17. C# métodos de extensión ambiguos
- 18. Métodos de extensión en Python
- 19. Métodos de extensión no reconocidos
- 20. ¿Cómo se definen los métodos de extensión para la clase genérica?
- 21. Los métodos estáticos de extensión de apoyo limitaciones miembros
- 22. Uso de IoC en los métodos de extensión
- 23. ¿Deben los métodos de extensión tener un prefijo?
- 24. Mejores prácticas: C# Espacio de nombres de métodos de extensión y promoción de métodos de extensión
- 25. Por favor, explique los métodos de extensión para mí
- 26. ¿Cómo se conectan los servicios de VoIP a las líneas fijas?
- 27. Memcache conectan vs addServer
- 28. ¿Podría abstraer sus consultas LINQ en los métodos de extensión
- 29. métodos de extensión en T4
- 30. Los métodos de extensión para tipos genéricos específicos
1 buen punto :) –