views:

109

answers:

3

I came across a situation where I would like to step back through the app's methods up the "tree" until I decided to catch it (if I do) - like an exception; it's raised through all the code until you catch it or hits the roof.

The general concensus is that you only use exception for exceptions. That being the case, what would be the mechanism to apply an exception like pattern in code but not necessarily an exception?

Is an exception the right mechanism to use? In this case, an exception does what's needed - but by strict definition it's not an exception.

Is there an event pattern or class I'm not aware of?

Edit
Just to clarify - my initial design would be to create a custom exception - since exception fits the bill. But this isn't an exception - it's a decision to go back through the code until I catch it or not - depending. I'm thinking custom exception - but want to make sure there isn't a class/patter that handles this.

Update

I ended throwing a custom exception. While I always thought this was the best pattern/method to what I wanted, I didn;t like the use of an exception for this - since it's not an exception. But ultimately, an exception is the perfect solution.

A: 

You could derive your own inherited exception class and then throw that, this specific exception could then be handled in your own specific way.

benPearce
That's my initial inclination - but this isn't an exception per say. Wondering if there's something else.
Tony Basallo
+2  A: 

The design pattern you're looking for is called a continuation, where you pass a point of return as a value to other functions:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            p.Start();
        }

        void Start()
        {
            Console.WriteLine("Start");
            Step1(1);
            Console.WriteLine("End Start");
            Console.ReadKey(true);
        }

        void Step1(int state)
        {
            Console.WriteLine("Step1: {0}", state);
            Step2(2, () => {
                Console.WriteLine("Continuation from step1: {0}", state);
            });
            Console.WriteLine("End Step 1");
        }

        void Step2(int state, Action continuation)
        {
            Console.WriteLine("Step2: {0}", state);
            Step3(3, continuation);
            Console.WriteLine("End Step 2");
        }

        void Step3(int state, Action continuation)
        {
            Console.WriteLine("Step3: {0}", state);
            continuation();
            Console.WriteLine("End Step 3");
        }
    }
}

Step 3 jumps back up to step 1 through the continuation. This program outputs the following:

Start
Step1: 1
Step2: 2
Step3: 3
Continuation from step1: 1
End Step3
End Step2
End Step 1
End Start

Continuation passing style is very powerful, but isn't a very natural idiom in C#. Use with care.

Juliet
A: 

Depending on the actual scenario the GoF pattern chain of responcibility might suit your needs. Chain of responcibility forwards a task along a chain of possible handlers until one eventually handles the task or the chain ends.

Rune FS