I agree that exceptions from C++ constructors can be dangerous, although you can dealing with them safely if you're careful. Yes this is fine in .NET. However, exceptions from C++ destructors are always dangerous, and this is still true in .NET.
In C++, if an exception can escape a destructor, it means it could get thrown while doing the stack-unwind due to processing another exception. Since you can't propagate two exceptions at the same time, std::terminate() is called (not sure what the default behaviour under Visual C++ is, probably kill the process). Bjarne Stroustrup (creator of C++) describes this as "a failure of the exception handling mechanism". In .NET if you throw an exception from a finalizer, it's just treated as an unhandled exception and shouldn't be problem any more than any other unhandled exception (i.e. it does not terminate the finalizer thread, future finalizations still happen). But the closest thing to C++ destructors in .NET aren't really finalize methods (which you want to avoid as much as possible), it's Dispose methods (which you should use whenever you need cleanup). Throwing an exception from a Dispose method leads to the same problem as in C++: which exception should be propagated? Instead of taking the idealist approach of C++ ("this is a serious failure, can't reasonably choose"), .NET takes a perhaps more intuitive choice: if exception B is thrown from a finally block while unwinding the stack for exception A (eg. from a Dispose call due to a 'using' statement), just throw away all the information about exception A and instead propagate exception B. (Surprisingly, I couldn't find this behaviour mentioned explicitly in the CLI spec, am I just missing it?). In my opinion, the .NET behaviour is almost worse than the C++ behaviour. I have seen many situations where a rare bug gets triggered, and the exception details are thrown away and replaced with a new exception generated inside a finally block. So all I get in my logs are the details of the 2nd exception , not the 1st one that actually caused the problem. Of course the solution is to prevent throwing exceptions from my finally blocks, but this can be very hard to guarantee, and you generally won't discover a problem until you've lost information about a more important bug that needs to be tracked down. I kind of wish that any exception thrown from a finally block was treated as unhandled and didn't interrupt the processing of the original exception. Rick ----- Original Message ----- From: "Chris Snyder" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Wednesday, March 31, 2004 9:29 AM Subject: Exceptions in Constructors > I have a (hopefully) simple question. > > In a nutshell, as a C++ developer, various people hammered into my brain > that throwing an exception in a constructor (whether intentionally or by > performing some action which would cause an exception to be thrown) was > extremely bad. However, my research seems to indicate that .NET handles > constructors differently, allowing developers to perform actions in a > constructor that may result in exceptions being thrown, or to <gasp> even > throw an exception themselves. > > Thoughts? > > Thanks a lot, > Chris Snyder > > =================================== > 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 > =================================== 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