2011-03-23 8 views
10

Soy nuevo en C# y trato de entender los conceptos básicos. Gracias de antemano por su ayuda. Tengo algunas clases de muestra a continuación (mecanografiadas en esta ventana lo que puede haber algunos errores) y tienen dos preguntas:Ampliando un método de clase base

  1. ¿Es posible llamar a un método de la clase derivada que ejecuta el código en el método de la clase base con el mismo nombre, luego ejecuta el código en el método de clase derivada? Todas las clases derivadas deberán ejecutar el código de clase base para RunCheck y luego realizar un código especializado específico para su clase. Podría nombrar RunCheck() algo más en la clase base y luego llamarlo cuando llame al RunCheck() de la clase derivada, pero luego debo recordar llamarlo en RunCheck() en la clase derivada.

  2. En el Program.cs quiero mostrar todos los campos con un valor en blanco si está en un campo que no está en la clase derivada que paso. ¿Qué pasaría?

Aquí está mi código:

class baseCheck 
    { 
     public DateTime StartTime { get; set; } 
     public DateTime LastRun { get; set; } 
     public int Runs { get; set; } 
     //Others 

     public void RunCheck() 
     { 
     if (Started != null) 
      started = DateTime.Now; 

     LastRun = DateTime.Now; 

     Runs++; 
     } 
    } 

    class FileCheck : baseCheck 
    { 
     public string FileName { get; set; } 

     public void RunCheck() 
     { 
      //I want all the code in the base class to run plus 
      //any code I put here when calling this class method 

     } 
    } 
    class DirectoryCheck : baseCheck 
    { 
     public string DirectoryName { get; set; } 

     public void RunCheck() 
     { 
      //I want all the code in the base class to run plus 
      //any code I put here when calling this class method 

     } 
    } 

     //Program.cs 
     static void Main() 
     { 
      //Create derived class - either DirectoryCheck or FileCheck 
      //depending on what the user chooses. 

      if (Console.ReadLine()=="F") 
      { 
       FileCheck c = new FileCheck(); 
      } 
      else 
      { 
       DirectoryCheck c = new DirectoryCheck(); 
      } 

      PrintOutput(c); 

     } 
     private void PrintOut(What do I put here?) 
     { 
      Console.WriteLine("Started: {0}",f.StartTime) 
      Console.WriteLine("Directory: {0}", f.DirectoryName) 
      Console.WriteLine("File: {0}", f.FileName} 
     } 
+0

En su método derivado, llame a 'super.RunCheck()'.Llamará al método de clase padre. – Doodloo

Respuesta

22

Sólo tiene que llamar base.RunCheck() en su clase DirectoryCheck:

public class DirectoryCheck : baseCheck 
{ 
    public string DirectoryName { get; set; } 

    public void RunCheck() 
    { 
     //I want all the code in the base class to run plus 
     //any code I put here when calling this class method 
     base.RunCheck(); 
     Console.WriteLine("From DirectoryCheck"); 
    } 
} 

también con su aplicación actual que está ocultando la RunCheck() método de clase base - que debe realmente anularlo - esto cambia la firma del método en la clase base al

public virtual void RunCheck() 

y en las clases derivadas

public override void RunCheck() 

Sospecho que lo que realmente quiere, aunque es algo así como el Non Virtual interface patrón (NVI) - Exponer un método virtual protegida en su clase base, que las clases niño puede anular, pero tiene un método público en la clase base que realmente está llamando a ese método internamente - este enfoque le permite extender lo que está haciendo antes y después de esa llamada.

En el ejemplo, esto se vería así:

class BaseCheck 
{ 
    private DateTime Started { get; set; } 
    public DateTime StartTime { get; set; } 
    public DateTime LastRun { get; set; } 
    public int Runs { get; set; } 
    //Others 

    public void RunCheck() 
    { 
     if (Started != null) 
      Started = DateTime.Now; 

     LastRun = DateTime.Now; 
     Runs++; 
     CoreRun(); 
    } 

    protected virtual void CoreRun() 
    { 

    } 
} 


public class DirectoryCheck : BaseCheck 
{ 
    public string DirectoryName { get; set; } 

    protected override void CoreRun() 
    { 
     //I want all the code in the base class to run plus 
     //any code I put here when calling this class method 
     Console.WriteLine("From DirectoryCheck"); 
    } 
} 
+0

Haría 'BaseClass'' abstract' y usaré 'abstract'' CoreRun' isntead de 'virtual'. – Aron

+0

o de la otra manera sería inyectar una clase 'CheckerCore' en la clase' BaseCheck'. – Aron

3

En una clase derivada, se puede llamar al método en la clase base usando:

public override void RunCheck() 
{ 
    base.RunCheck(); 

    // Followed by the implementation of the derived class 
} 

Como se mencionó en los comentarios, la tendrá que ser declarada método de base como para permitir virtual primordial:

public virtual void RunCheck() { ... } 

Para su método PrintOut(), no hay una forma mágica, pero podría hacer que tome la clase base como parámetro y luego probar para el tipo.

private void PrintOut(baseCheck f) 
{ 
    Console.WriteLine("Started: {0}", f.StartTime) 
    Console.WriteLine("Directory: {0}", f.DirectoryName) 

    if (check is FileCheck) 
    { 
     Console.WriteLine("File: {0}", ((FileCheck)f).FileName} 
    } 
} 

o puede utilizar las sobrecargas:

private void PrintOut(baseCheck f) 
{ 
    Console.WriteLine("Started: {0}", f.StartTime) 
    Console.WriteLine("Directory: {0}", f.DirectoryName) 
} 

private void PrintOut(FileCheck f) 
{ 
    PrintOut((baseCheck)f); 

    Console.WriteLine("File: {0}", ((FileCheck)f).FileName} 
} 

O usted podría tener su parte método de impresión de su clase (tal vez incluso utilizar el método existente ToString()) y modificarlo así se requiere.

+0

+1 si menciona que el método de la clase base debe ser virtual. – Kimberly

+0

Gracias - ha sido agregado –

Cuestiones relacionadas