2010-07-27 694 views
6

¿Por qué no se compila lo siguiente?¿Por qué un método prefijado con el nombre de la interfaz no se compila en C#?

interface IFoo 
{ 
void Foo(); 
} 

class FooClass : IFoo 
{ 
void IFoo.Foo() { return; } 

void Another() { 
    Foo(); // ERROR 
} 
} 

El compilador se queja de que "El nombre 'FooMethod' no existe en el contexto actual".

Sin embargo, si se cambia el método de Foo a:

public void Foo() { return; } 

esta compila bien.

No entiendo por qué uno funciona y el otro no.

Respuesta

2

Prueba esto:

void Another() { 
    ((IFoo)this).Foo(); 
} 

Puesto que usted está declarando el método de Foo como explicit interface implementation, no se puede hacer referencia a ella en una instancia de FooClass. Solo puede referenciarlo lanzando la instancia de FooClass a IFoo.

0

Lo que usted tiene en su código se llama implementación de interfaz explícita. Si opta por admitir una interfaz como esta, estos métodos de interfaz de su clase no son públicos y solo pueden invocarse a través de las referencias de tipo de interfaz apropiadas (IFoo en su ejemplo).

1

En realidad, hay una buena razón para este comportamiento. Considera el siguiente código.

public interface IA 
{ 
    IA DoSomething(); 
} 

public interface IB 
{ 
    IB DoSomething(); 
} 

public class Test : IA, IB 
{ 
    public IA DoSomething() { return this; } 

    IA IA.DoSomething() { return this; } 

    IB IB.DoSomething() { return this; } 
} 

En este escenario la clase Test debe implementar al menos uno de los métodos DoSomething explícitamente porque no es legal para declarar dos métodos diferentes con la misma firma. Si tuviera que examinar el IL, vería que implementar explícitamente una interfaz decora automáticamente el nombre del miembro para que no haya dos miembros con el mismo nombre en la misma clase. Y para poder invocar cada una de las 3 variaciones diferentes de DoSomething arriba, debe invocar al miembro desde una referencia del tipo correcto. Así es como el compilador sabe vincularse al miembro correcto.

public static void Main() 
{ 
    var test = new Test(); 
    test.DoSomething(); // Compiler binds to the implicit implementation. 
    var a = (IA)test; 
    a.DoSomething(); // Compiler binds to the IA implementation. 
    var b = (IB)test; 
    b.DoSomething(); // Compiler binds to the IB implementation. 
} 
Cuestiones relacionadas