2010-07-26 22 views
5

No puedo hacer esto¿Cómo implementar una interfaz explícitamente con un método virtual?

interface InterfaceA 
{ 
    void MethodA(); 
} 

class ClassA : InterfaceA 
{ 
    virtual void InterfaceA.MethodA() 
    // Error: The modifier 'virtual' is not valid for this item 
    { 
    } 
} 

Donde las siguientes obras

class ClassA : InterfaceA 
{ 
    public virtual void MethodA() 
    { 
    } 
} 

¿Por qué? ¿Cómo eludir esto?

+1

¿Por qué quiere eludirlo? ¿Qué beneficio agrega eso? –

+0

@Eric Me ahorrará un poco de mecanografía –

+0

¿Cómo no se permite marcar un método de interfaz explícito como virtual porque te da más tipeo? –

Respuesta

8

Creo que esto se debe a que cuando un miembro es implementado de manera explícita, no se puede acceder a través de una instancia de clase, pero solo a través de una instancia de la interfaz.

Por lo tanto, hacer algo 'virtual' realmente no tiene sentido en este caso, ya que virtual significa que tiene la intención de anularlo en una clase heredada. Implementar una interfaz explícitamentey por lo que es virtual sería contradictorio. Que también puede ser por qué el compilador no permite esto.

Para evitar que creo csharptest.net's o Philip's respuesta suena como lo haría el truco

+0

Buena explicación de por qué no tiene sentido querer eso. – user276648

0

No puede usar el modificador virtual con los modificadores estáticos, abstractos, privados o anular. modificador por defecto es privada

+0

Interesantemente para implementaciones explícitas, el modificador es público, aunque solo se puede acceder si la instancia se convierte al tipo de interfaz respectivo. –

3

De acuerdo con el lenguaje C# spec:

Es un error en tiempo de compilación para un miembro de interfaz explícita implementación para incluir los modificadores de acceso , y es un error en tiempo de compilación para incluir los modificadores abstracto, virtual, anular o estático.

Puede "moverse" solo llamando a su método virtual desde la implementación de la interfaz explícita.

3

que tiene que hacer algo como esto:

interface InterfaceA 
{ 
    void MethodA(); 
} 

class ClassA : InterfaceA 
{ 
    void InterfaceA.MethodA() 
    { MethodB(); } 

    protected virtual void MethodB() 
    { 
    } 
} 

A menudo, este es un enfoque superior de todos modos como el método interno puede cambiar la firma sin cambiar la interfaz. Tome una palabra real ejemplo más:

interface IOrderDetails 
{ 
    void PlaceOrder(); 
} 

//Sometime later you extend with: 
interface IOrderDetails2 : IOrderDetails 
{ 
    void PlaceOrder(IUser user); 
} 

//Implementation 
class Order : IOrderDetails, IOrderDetails2 
{ 
    static readonly IUser AnonUser; 

    void IOrderDetails.PlaceOrder() 
    { OnPlaceOrder(AnonUser); } 
    void IOrderDetails2.PlaceOrder(IUser user) 
    { OnPlaceOrder(user); } 

    protected virtual void OnPlaceOrder(IUser user) 
    { 
    } 
} 

Aquí se puede ver que se añadió la IOrderDetails2 podemos refactorizar con seguridad el método virtual existente (lo que genera errores en tiempo de compilación para derivaciones). Además, esto a menudo le permite proporcionar funcionalidad común, registro y manejo de excepciones en la clase de implementación base ...

Cuestiones relacionadas