2010-07-19 14 views
8

Así que en el trabajo estaba usando una API que no escribimos, y uno de los métodos tomó un delegado. Por una razón u otra, se me ocurrió que tengo un método de extensión que se ajusta a esa firma, por lo que me preguntaba si funcionaría. Estaba seguro de que no sería para mi sorpresa, pero sí lo fue. Permítanme demostrar:Pasar un método de extensión a un método que espera un delegado. ¿Como funciona esto?

Decir que tengo estas clases:

public interface IMyInterface 
{ 

} 

public class MyClass : IMyInterface 
{ 

} 

public static class Extensions 
{ 
    public static string FuncMethod(this IMyInterface imy, int x) 
    { 
     return x.ToString(); 
    } 
} 

Ahora vamos a decir que tengo una firma de método en alguna parte que se ve así:

private static void Method(Func<int, string> func) 
    { 

    } 

Ahora método de mi extensión (se parece que) coincide con esa firma, pero todos sabemos que los métodos de extensión son solo humo y espejos, por lo que realmente no coincide con esa firma. Sin embargo, puedo hacer esto de manera segura:

var instance = new MyClass(); 
Method(instance.FuncMethod); 

Mi pregunta es, ¿cómo funciona esto? ¿Qué genera el compilador para que lo haga aceptable? La firma real del método de extensión toma una instancia de IMyInterface, pero el Func no lo hace, ¿qué está pasando aquí detrás de mi?

Respuesta

7

Los métodos de instancia se implementan teniendo en cuenta el parámetro oculto this.

Cuando crea un delegado de instancia desde un método de extensión, el parámetro this oculto se pasa al método como el primer parámetro normal.

Note that this cannot be done with value types.

0

No sé exactamente qué está haciendo el compilador para permitir estos escenarios, pero las expectativas parecen razonables. Tal vez esta muestra de código ayude a lidiar con el concepto.

MyClass instance = new MyClass(); 
Func<int, string> f1 = instance.FuncMethod; 
Func<int, string> f2 = (i) => instance.FuncMethod(i); 
Func<int, string> f3 = (i) => Extensions.FuncMethod(instance, i); 
Cuestiones relacionadas