Extending a base class method

43,662

Solution 1

Just call base.RunCheck() in your DirectoryCheck class:

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");
    }
}

Also with your current implementation you are hiding the base class RunCheck() method - you should really override it - this changes the method signature in the base class to

    public virtual void RunCheck()

and in the derived classes to

    public override void RunCheck()

I suspect what you really want though is something like the Non Virtual interface pattern (NVI) - Expose a protected virtual method in your base class, that child classes can override, but have a public method on the base class that is actually calling that method internally - this approach allows you to extend what you are doing before and after that call.

In your example this would look like this:

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");
    }
}

Solution 2

In a derived class, you can call the method in the base class using:

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

    // Followed by the implementation of the derived class
}

As mentioned in the comments, the base method will need to be declared as virtual to allow overriding:

public virtual void RunCheck() { ... }

For your PrintOut() method, there is no magic way, but you could have it take the base class as a parameter, and then test for the type.

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}
   }
}

Or you could use overloads:

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}
}

Or you could have your PrintOut method part of your class (maybe even use the existing ToString() method) and override it as required.

Share:
43,662
Admin
Author by

Admin

Updated on July 09, 2022

Comments

  • Admin
    Admin almost 2 years

    I am new to C# and am trying to understand basic concepts. Thank you in advance for your help. I have some sample classes below (typed in this window so there may be some errors)and have two questions:

    1. Is it possible to Call a derived class method that executes the code in the base class method with the same name, then executes the code in the derived class method? Every derived class will need to perform the base class code for the RunCheck then do specialized code specific to its class. I could name RunCheck() something else in the base class and then call it when I call the RunCheck() of the derived class but then I have to remember to call it on the RunCheck() in the derived class.

    2. In the Program.cs I want to output all fields with a blank value if it is on a field that is not in the derived class I pass in. What would I pass in?

    Here is my code:

      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}
            }
    
  • Aron
    Aron about 10 years
    I would make BaseClass abstract and use an abstract CoreRun isntead of virtual.
  • Aron
    Aron about 10 years
    or the other way would be to inject a CheckerCore class into the BaseCheck class.