2009-08-26 13 views

Respuesta

78

El uso de las construcciones del lenguaje C#, no se puede llamar explícitamente a la función de base de fuera del alcance de A o B. Si realmente necesita hacer eso, entonces hay un defecto en su diseño, es decir, que la función no debe ser virtual para empezar, o que parte de la función base debe extraerse a una función no virtual separada.

Puede desde el interior B.X sin embargo llamar A.X

class B : A 
{ 
    override void X() { 
    base.X(); 
    Console.WriteLine("y"); 
    } 
} 

Pero eso es otra cosa.

Como señala Sasha Truf en this answer, puede hacerlo a través de IL. Probablemente también pueda lograrlo a través de la reflexión, como señala Mhand en los comentarios.

+6

(Hola Sólo para que conste, alguien suprime la etiqueta del 'estúpida-truco que he añadido, y entonces alguien De lo contrario, eliminé el comentario que lo señalaba, haciendo que pareciera que realmente quiero/necesito hacer esto. Sería útil recibir notificaciones de las ediciones tontas que la gente parece querer hacer en SO.) – mackenir

+0

Llamando a AX() desde el interior B es la única situación en la que incluso puedo ver que necesitas llamarla una vez desautorizada. Supongamos que tiene un método de copia con los miembros de la clase base, luego anule para agregar funcionalidad de copia para los miembros nuevos y llame a base.copy() adentro para que todo se copie. – steviesama

+0

Interesante, ¿hubiera pensado que se podría lograr a través de la reflexión? – mhand

6

No puede y no debe. Para eso está el polimorfismo, para que cada objeto tenga su propia forma de hacer algunas cosas "básicas".

7

Puede hacerlo, pero no en el punto que ha especificado. Dentro del contexto de B, puede invocar A.X() llamando al base.X().

4

I konow es la pregunta de la historia ahora. Pero para otros googlers: podrías escribir algo como esto. Pero esto requiere un cambio en la clase base, lo que lo hace inútil con las bibliotecas externas.

class A 
{ 
    void protoX() { Console.WriteLine("x"); } 
    virtual void X() { protoX(); } 
} 

class B : A 
{ 
    override void X() { Console.WriteLine("y"); } 
} 

class Program 
{ 
    static void Main() 
    { 
    A b = new B(); 
    // Call A.X somehow, not B.X... 
    b.protoX(); 


    } 
10

No puede hacerlo por C#, pero puede editar MSIL.

código IL importar el método principal:

.method private hidebysig static void Main() cil managed 
{ 
    .entrypoint 
    .maxstack 1 
    .locals init (
     [0] class MsilEditing.A a) 
    L_0000: nop 
    L_0001: newobj instance void MsilEditing.B::.ctor() 
    L_0006: stloc.0 
    L_0007: ldloc.0 
    L_0008: callvirt instance void MsilEditing.A::X() 
    L_000d: nop 
    L_000e: ret 
} 

Debe cambiar código de operación en L_0008 de callvirt a llamada

L_0008: call instance void MsilEditing.A::X() 
2

Es imposible si el método se declara en el clase derivada como overrides. Para ello, el método en la clase derivada debe ser declarado como new:.

public class Base { 

    public virtual string X() { 
     return "Base"; 
    } 
} 
public class Derived1 : Base 
{ 
    public new string X() 
    { 
     return "Derived 1"; 
    } 
} 

public class Derived2 : Base 
{ 
    public override string X() { 
     return "Derived 2"; 
    } 
} 

Derived1 a = new Derived1(); 
Base b = new Derived1(); 
Base c = new Derived2(); 
a.X(); // returns Derived 1 
b.X(); // returns Base 
c.X(); // returns Derived 2 

See fiddle here

Cuestiones relacionadas