views:

33

answers:

3

I'm trying to create an abstract class, defining an abstract method, that is to be derived from other classes that implements some specific behavior in the abstract method. I want the abstract class to contain some kind of state information that represents however the implementation in the derived classes exited without errors, but I want to implement all state handling in AbstractClass and not in the deriving classes. I want to make the deriving classes totally unaware of the functionality in AbstractClass. Below is an example. I made comments in the code to describe what I'm trying to achieve.

public abstract class AbstractClass
    {
        public void Start()
        {
            ThreadStart ts = new ThreadStart(PerformWork);
            Thread t = new Thread(ts);
            t.Start();
            Thread.Sleep(2000);

            // Dependent on if ReportWork exited without expcetions
            // I want to call ReportSuccess or ReportFailure from this method.
            // However, I dont want to implement any reporting functionallity (or
            // as little as possible)
            // into the deriving classes PerformWork() method. Simply put
            // I want the deriving classes to be totally unaware of the reporting. 

        }

        public void ReportSuccess()
        {
            Console.WriteLine("Success!");
        }

        public void ReportFailure()
        {
            Console.WriteLine("Failure!");
        }
        public abstract void PerformWork();
    }

A class deriving from AbstractClass:

class ConcreteImplementationClass:AbstractClass
    {
        public override void PerformWork()
        {
            // Implements some functionality
            // without knowing anything about
            // whats going on in AbstractClass.           
        }
    }

Do anyone have any advice for how I could achieve this functionality, or how I could create something similar?

A: 

Can you not make your base method virtual, given that you want to run code in it, then call base.PerformWork() in all the derived methods?

Paul Manzotti
because that would mean the derived class must be aware of implementation details of the abstract base. Not a bad thing but the thing the OP explicitly stated as undesirable.
Sky Sanders
Yes I could, but I hoped for some really neat way of doing it without making method calls to the base class from the derived classes.
Clean
+1  A: 

If I understand this correctly you want to call ReportSuccess() if the PerformWork() is successfully and ReportFailure() if it fails?

Why not change

public abstract void PerformWork();

to

public void Start()
{
    bool result = false;

    // This will enable Perform work to operate in its own thread
    Action threadAction = new Action(() =>
        {
            result = PerformWork();
        });

    ThreadStart ts = new ThreadStart(threadAction);
    Thread t = new Thread(ts);
    t.Start();
    Thread.Sleep(2000);

    // Dependent on if ReportWork exited without expcetions
    // I want to call ReportSuccess or ReportFailure from this method.
    // However, I dont want to implement any reporting functionallity (or
    // as little as possible)
    // into the deriving classes PerformWork() method. Simply put
    // I want the deriving classes to be totally unaware of the reporting. 

    if(result)
    {
        ReportSuccess();
    }
    else
    {
        ReportFailure();
    }
}
David Basarab
Because then PerformWork would not run on it's own separate thread.
Clean
@Clean - I modified the snippet to use an Action to have Perform work in its own thread. You could move the ReportSucess and Failure in that thread too. I did not because I do not know what you are trying to achieve.
David Basarab
Thank you for the help! I think this is as close as I can get to my desired behavior (without getting in to AOP).
Clean
A: 

You are describing Aspect Oriented Programming, AOP.

You can easily achieve this using any number of intercept strategies. The easiest would probably be castle proxy.

See this...

Sky Sanders