2011-11-30 19 views
21

estoy tratando de refrescar mi memoria, pero no puede encontrar respuestas con Google.Convertir a clase base

public class BaseClass 
{ 
    public virtual void DoSomething() 
    { 
     Trace.Write("base class"); 
    } 
} 

public class DerivedClass : BaseClass 
{ 
    public override void DoSomething() 
    { 
     Trace.Write("derived class"); 
    } 
} 

Si creo una instancia de la clase derivada, ¿cómo convertirlo a su clase base, de manera que cuando se llama HacerAlgo(), se utiliza el método de la clase base única?

Un elenco dinámico todavía llama método reemplazado de la clase derivada:

DerivedClass dc = new DerivedClass(); 

dc.DoSomething(); 

(dc as BaseClass).DoSomething(); 

salida: "clase derivada"

+1

tipo de derrotas el propósito de la herencia, por lo general en su anulación, aunque debe invocar manualmente 'base.DoSomething () 'pero salvo que puedas hacer algo con reflexión. –

+0

Ouch, pensé que sería algo simple que pasé por alto. Gracias – Levitikon

+0

posible duplicado de [Cómo invocar (no virtualmente) la implementación original de un método virtual?] (Http://stackoverflow.com/questions/3378010/how-to-invoke-non-virtually-the-original-implementation -of-a-virtual-method) – Ani

Respuesta

29

no se puede - eso es totalmente deliberada, ya que eso es lo que el polimorfismo se trata. Supongamos que tiene una clase derivada que impone ciertas condiciones previas en los argumentos que pasa a un método reemplazado, para mantener la integridad ... no desea poder eludir esa validación y dañar su integridad interna.

Dentro de la clase en sí no puede llamar virtualmente al base.AnyMethod() (si ese es el método que está anulando o no) pero está bien porque es la clase la que decide potencialmente violar su integridad, presumiblemente sabe lo que es obra.

+0

Gracias Jon. Quiero dejarlo en claro, disfruto mucho y confío en que las propiedades y los métodos de las clases derivadas estén en vigencia incluso cuando la clase se convierte en su clase base. Sería muy agradable también eliminar clases derivadas bajo ciertas condiciones especiales. Parece que la reflexión o algún tipo de copia profunda es el camino a seguir. – Levitikon

+0

¿Estamos seguros de que esta es la respuesta correcta? Parece que puede llamar al método base si la clase derivada utilizó la palabra clave nueva en lugar de anular a un miembro virtual de la clase base. – winnicki

+0

@winnicki: En ese momento no es la misma situación que en la pregunta. Podría llamar al método de la clase base si no tuviera el método de clase derivado en absoluto, o si tuviera un nombre diferente, o un número diferente de parámetros, etc. ... –

3

Intente utilizar el new keywor en lugar de override Por lo que sé, esto debería permitir que el comportamiento deseado. No estoy muy seguro de eso así que por favor no me culpen si estoy equivocado.

public class BaseClass 
{ 
    public virtual void DoSomething() 
    { 
     Trace.Write("base class"); 
    } 
} 

public class DerivedClass : BaseClass 
{ 
    public new void DoSomething() 
    { 
     Trace.Write("derived class"); 
    } 
} 
7

Usted puede absolutamente (llamar al método de base), acaba de leer sobre Polimorfismo:

http://msdn.microsoft.com/en-us/library/ms173152(v=VS.80).aspx

Ejemplo:

public class BaseClass 
{ 
    public void DoWork() { } 
    public int WorkField; 
    public int WorkProperty 
    { 
     get { return 0; } 
    } 
} 

public class DerivedClass : BaseClass 
{ 
    public new void DoWork() { } 
    public new int WorkField; 
    public new int WorkProperty 
    { 
     get { return 0; } 
    } 
} 

Y cómo llamarlo:

DerivedClass B = new DerivedClass(); 
B.DoWork(); // This calls the new method. 

BaseClass A = (BaseClass)B; 
A.DoWork(); // This calls the old method. 
+0

Hola, estoy recibiendo un error en Visual Studio en su línea –

21

Aunque esto suena irracional pero funciona

DerivedClass B = new DerivedClass(); 

BaseClass bc = JsonConvert.DeserializeObject<BaseClass>(JsonConvert.SerializeObject(B)); 
+2

La copia profunda es una de las soluciones aceptables, pero tiene un costo de rendimiento. – Levitikon

+1

¿Dónde pone esto las propiedades adicionales que pueden estar en la clase derivada al serializar en la clase base? P.ej. La clase StudentDerived presentó Height of student mientras hereda de StudentBase. – Vaibhav

+1

@Vaibhav Simplemente ignora todas las propiedades adicionales :) –

2

Las soluciones con new en lugar de override ruptura del polimorfismo. Recientemente llegué al mismo problema y lo implementé de la siguiente manera. Mi solución tiene las siguientes ventajas:

  • virtual y override permanece en su lugar;
  • nombre BaseClass no se utiliza directamente en el molde tipo, así que si presento un intermedio MiddleClass en la jerarquía entre BaseClass y DerivedClass, que también implementa DoSomething(); entonces la implementación de MiddleClass no se saltará.

Esta es la implementación:

public class BaseClass 
{ 
    public virtual void DoSomething() 
    { 
     Trace.Write("base class"); 
    } 
} 

public class DerivedClass : BaseClass 
{ 
    public override void DoSomething() 
    { 
     Trace.Write("derived class"); 
    } 

    public void BaseDoSomething() 
    { 
     base.DoSomething(); 
    } 
} 

El uso es:

DerivedClass dc = new DerivedClass(); 

    dc.DoSomething(); 

    dc.BaseDoSomething(); 
Cuestiones relacionadas