Pregunta

Tengo dos clases:

public class MyBase
{
    public virtual void DoMe()
    {

    }
}

public class MyDerived:MyBase
{
    public override void DoMe()
    {
        throw  new NotImplementedException();
    }
}

Y tengo el siguiente código para crear una instancia de MyDerived:

        MyDerived myDerived=new MyDerived();

¿Cómo llamar a DoMe de la clase base? Si uso myDerived.DoMe (), se llamará al método derivado, lo que dará como resultado una excepción. Traté de transmitir myDerived a MyBase, pero todavía se llama la versión derivada del método.

Editar: Como se menciona en el comentario a continuación, no puedo cambiar eitehr MyDerived o MyBase porque no son mi código.

¿Fue útil?

Solución

Hay una solución, pero es fea: use la reflexión para obtener el método de la clase base y luego emita la IL necesaria para llamarlo. Echa un vistazo a esta publicación de blog que ilustra cómo hacerlo esta. He utilizado con éxito este enfoque para llamar a la implementación de un método de la clase base cuando todo lo que tengo es una referencia a una clase derivada que anula ese método.

Otros consejos

No se puede llamar a la versión de clase base.

Si el método no funciona en la clase derivada, es poco probable que la versión base del método funcione cuando se llama en una instancia de la clase derivada. Eso es solo pedir problemas. La clase no fue diseñada para funcionar de esa manera, y lo que intentas hacer probablemente hará que otras partes de la clase se comporten de manera impredecible.

¿Por qué necesita llamar a este método en el objeto cuando el objeto le dice directamente que no funcionará?

Me parece que estas clases tienen algunos defectos de diseño, y si no se le permite cambiar las clases, tal vez se le permita cambiar a una biblioteca mejor diseñada en su lugar.

Para llamar a MyBase.DoMe () desde una clase externa, necesitaría una instancia de MyBase o una instancia derivada que no anule DoMe (). Se llamará a un método declarado como virtual en el tipo de tiempo de ejecución real del objeto, no en el tipo del objeto, por lo que la conversión a MyBase no cambia el método que se llama. Sin embargo, si el método no se declarara en MyBase como virtual y MyDerived todavía implementara DoMe (), estaría "ocultando". La implementación de MyBase. Por lo tanto, si la referencia fuera MyDerived, llamaría a MyDerived.DoMe (), pero en este caso enviar a MyBase myBase = (MyBase) myDerived y luego llamar a myBase.DoMe () llamaría a MyBase.DoMe ().

La clase derivada no necesita proporcionar una implementación del método. Elimínelo y se llamará a la implementación en la clase base de forma predeterminada.

Si, a diferencia de su ejemplo, el método en la clase base es abstracto y debe proporcionar una implementación pero no tiene sentido que la clase derivada proporcione una, entonces probablemente haya algo mal con el diseño de las clases.

public class MyDerived:MyBase{    
    public override void DoMe()    
    {        
        base.DoMe();
    }
}

EDIT:

No puede acceder al método de clases base desde " fuera de " sin pasar por el método de subclases. Su única opción es crear una instancia de su clase base directamente y llamar a su método.

MyBase mb = new MyBase();
mb.DoMe();

Dadas sus restricciones, existe otra posibilidad:

Descargar .Net Reflector. Descompile el código existente y luego realice los cambios que necesite para respaldar su situación.

Por supuesto, revise la legalidad de esto antes de continuar.

Esta pregunta es muy antigua pero no veo la siguiente opción:

Puede usar la palabra clave 'nuevo' para especificar métodos superpuestos. Entonces simplemente enviaría a la clase a cuyo método desea llamar.

    public class MyBase
    {
        public virtual void DoMe()
        {

        }
    }

    public class MyDerived:MyBase
    {
//note the use of 'new' and not 'override'
        public new void DoMe()
        {
            throw  new NotImplementedException();
        }
    }

Implementación

var myDerived = new MyDerived();
var derivedDoMe = myDerived.DoMe();
var baseDoMe = ((MyBase)myDerived).DoMe();
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top