>> Since you can't propagate two exceptions
>> at the same time,
>
>Ironically .NET does offer us a way to propagate multiple exceptions --
the
>InnerException property gives each exception the potential,
effectively, to
>represent a linked-list of exceptions (composite design pattern).
>
>I agree (I think) with you: it would be nice if the CLR could somehow
>automatically populate the InnerException, if/when a new exception is
>thrown from within a finally block, during a stack-unwind.
>
>I can't think of any problems that would cause... except, well, if the
new
>exception already has a chain of inner exceptions. :)  But hey, like I
>said, it's effectively a linked list.  The original exception-chain can
>always be tacked on to the end, somehow, right? :/

Is it possible to put a circular reference in the exception hierarchy I
wonder? I notice that the InnerException property is read-only and
sealed, but there's probably a reflection based way to meddle with it.
I'm sure there is plenty of recursive exception reporting algorithms
that would stack overflow if you were nasty enough to throw someone such
an exception.. as a side note, I remember reading something about the
CLR not requiring exceptions to be derived from System.Exception too.

Someone commented that 'the object is not constructed' if an exception
is thrown from the constructor, but that's not true. It's true that a
reference to the new instance is not returned, but the instance is
always 'created' (I'm not sure what the definition is 'construction' is
in this case, but certainly an object id is allocated, etc.). This is
obviously the case, since you have access to the 'this' pointer inside
the constructor.

I hacked something together to check this out. As a result I've come up
with a new coding rule for myself: 'if the constructor is going to
throw, then the constructor has to guarantee that it hasn't configured
another instance with a reference to itself'. Of course, this is
immediately impractical given the way the WinForms designer and
InitializeComponent() works. Hmm.. not sure what to do.. In my view, at
least to some extent, construction should be 'atomic'. Consider the
example below, which leaks references to 'partially constructed'
instances to the invocation list of an event. This could cause all sorts
of crazy things to happen that would be difficult to diagnose.

If you run this code, you'll see three partially constructed classes
handle the publisher's event. This is definitely something to watch out
for.

At the end of the day, I tend to think of exceptions as being too
difficult to handle. I design my code such that exceptions don't happen.
If they do, then I have a bug and I need to fix it, I don't pretend that
I can really 'handle' an exception (obviously there are cases where you
have to, but I try to avoid these), despite its politically correct name
I still consider it an 'error' and I generally terminate my process. To
try and handle all the possible states that you could be in when you
receive an exception seems almost impossible to me.

John.

  public class EntryPoint {

    [STAThread]
    public static void Main(string[] args) {

      EventPublisher publisher = new EventPublisher();
      EventSubscriber subscriber = null;

      // construct and detach three subscribers
      for (Int32 i = 0; i < 3; i++) {

        try {
          // try to construct a subscriber
          subscriber = new EventSubscriber(publisher);
        }
        catch {
          // ignore construction exception
        }

        if (subscriber != null) {
          // construction was successfull, now detatch
          // NOTE: this won't execute in this example as construction
          // is never successful, meaning we can't detach the
          // subscriber
          subscriber.Detach();
        }
      }

      // notify all subscribers of publishers event
      // NOTE: three 'partially constructed' instances will be notifed
      // although the code on this method tends to indicate that there
      // should be no subscribers (assuming that construction is
'atomic'
      // to some extent).
      publisher.Notify();

      Console.ReadLine();
    }
  }

  public class EventPublisher {

    public event EventHandler SomeEvent;

    public void Notify() { this.OnSomeEvent(EventArgs.Empty); }

    private void OnSomeEvent(EventArgs e) { if (this.SomeEvent != null)
this.SomeEvent(this, e); }

  }

  public class EventSubscriber {

    private EventPublisher _publisher;
    private Boolean _isConstructed;

    public EventSubscriber(EventPublisher publisher) {

      // reference publisher
      this._publisher = publisher;

      // subscribe to publishers event (has the effect of passing
      // a reference to to this presently partially constructed
      // instance to the publisher)
      this._publisher.SomeEvent += new
EventHandler(this.SomeEventHandler);

      if (this._publisher != null) {
        // throw an exception during construction
        // NOTE: this is just for the sake of example
        throw new ApplicationException();
      }

      // flag construction as successfully completed.
      // NOTE: this will not be set and the value will remain
      // defaulted to 'false'.
      this._isConstructed = true;

    }

    public void Detach() {

      // if still attached, detach from the publisher

      if (this._publisher != null) {

        this._publisher.SomeEvent -= new
EventHandler(this.SomeEventHandler);
        this._publisher = null;

      }
    }

    private void SomeEventHandler(Object sender, EventArgs e) {

      // NOTE: for testing output the hashcode (inherited from Object
      // as the internal object id) and an indication of successful
      // instance creation.
      Console.WriteLine("Instance " + this.GetHashCode() + " handled
event. Constructed:" + this._isConstructed);

    }
  }

===================================
This list is hosted by DevelopMentorŪ  http://www.develop.com
Some .NET courses you may be interested in:

NEW! Guerrilla ASP.NET, 17 May 2004, in Los Angeles
http://www.develop.com/courses/gaspdotnetls

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to