Click here to Skip to main content
15,891,136 members
Please Sign up or sign in to vote.
5.00/5 (2 votes)
See more:
Hi,

This seems like a dumb question I should know the answer to but in the following code:

C#
MyType x = new MyType();


If the constructor throws an exception, does that prevent the assignment from happening?

I'm 99% sure the answer is 'Yes', but I can't seem to find a reference to it anywhere.


Kind wishes, patrick
Posted

Perhaps you are missing something important about exceptions, not constructors. Exception propagation goes "above" the usual call/return mechanism bases on the thread stack, it makes a "long jump" (old C/C++ developers in real-mode of Intel CPU might remember the idea) up the stack to the closest catch. So, not that anything failed, the whole context where x is created is removed from stack (think "stack unwinding").

Generally, the whole idea in Structured Exception Handling is replaced with something else. There are no "errors", essentially, there are no error statuses. The objects themselves are removed. This is a kind of a time machine: exception propagation jumps execution "back in time", to the moment where the context of x was not yet created. Let's compare:

C#
MyType SomeMethod(/* ... */) {
    MyType x = new MyType(); // exception here jumps out of the SomeMethod context and maybe its caller
    // ...
    return x;
}


with

C#
MyType SomeMethod(/* ... */) {
    try {
        MyType x = new MyType();
    } catch (SomeException) {}
    // ...
    return x; // won't compile, because x is not defined
}


and with

C#
MyType SomeMethod(/* ... */) {
    MyType x;
    try {
        MyType x = new MyType();
    } catch (SomeException) {}
    // ...
    return x; // won't compile, because x is not initialized
}


and, finally, with

C#
MyType SomeMethod(/* ... */) {
    MyType x = null;
    try {
        MyType x = new MyType();
    } catch (SomeException) {}
    // ...
    return x; // will return null, or whatever it was before calling the constructor
}


As you can see, there is no a room for any ambiguity.

Now, in practice, it's the best to use the very first option and avoid catching exceptions too locally. You want to let go. Ideally, exceptions should be caught in very few points, typically pretty far away from the point where they are thrown. That approach helps to isolate exception handling from "normal" processing: exceptions should be processed exceptionally. As Matt T Heffron correctly pointed out in hist important comment (see below), the exceptions should be caught where the exceptional behavior cab be best addressed. I call it "competency point".

[EDIT: the end of the previous and the next paragraphs have been modified, driven by the comment by Matt T Heffron.]

As a minimalistic "default" exception handling approach, all exceptions should be caught only on the very top of the stack of the stack of each thread. Event-oriented UI is a special case; you need to catch all exceptions in the uppermost loop, the application event loop. When this is done, some exceptions can be could for some special cases, according to the "competency point" approach. The cases when the all the exceptions really should be caught immediately in a very narrow context (as shown in my samples above) are pretty rare; for example, it is pretty typically needed to compensate for some poorly designed APIs with source code unreachable for a patch; in normal situations under the full control of the developers, such technique is best avoided.

Please see my past answers:
How do i make a loop that will stop when a scrollbar reaches the bottom[^],
Keep a c# windows form application running despite any unhandled exception[^],
When i run an application an exception is caught how to handle this?[^],
throw . .then ... rethrowing[^],
Error Logging and Screen Shot.[^],
Catching an Exception[^],
Handling exceptions in class library (dll)[^],
Exception Details: System.Runtime.InteropServices.COMException: Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to the following error:...[^].

—SA
 
Share this answer
 
v8
Comments
Matt T Heffron 20-Mar-13 15:08pm    
I would disagree with "Ideally, all exceptions should be caught only on the very top of the stack of the stack of each thread."
The exception(s) should be caught at the point in the calling hierarchy where the exceptional behavior is best addressed: by reporting/logging and/or correcting the condition.
Sometimes that is right at the call of the method throwing the exception.
For example, in a recent application I needed to scan a directory for folders which had localized resources and were named for the language/culture name. (E.g., "en", "jp", "zh-Hans"...) The .NET framework (CultureInfo class) has no function to verify that a string is a valid culture name, so I could not verify the name before attempting to create a CultureInfo object for that name. My only option was to wrap the call to CultureInfo.GetCultureInfo(name) in a try/catch; and ignore the CultureNotFoundException which would occur when the name of a directory that was NOT one of the resource directories was encountered.

Thus, my 4.
Sergey Alexandrovich Kryukov 20-Mar-13 15:34pm    
Of course, you are right!

My statement was "too quick", and due to this fact, oversimplified and, in fact, inaccurate. Also, the main point was the attempt to help to overcome a very bad trend to handle exceptions very locally, which defeats the purpose and lowers down the technique almost to the hell of "error status" approach.

Thank you for your note. I'll improve my answer soon, and of course will credit you for this help.
—SA
Sergey Alexandrovich Kryukov 20-Mar-13 15:51pm    
I use my own term for your idea of "where the exceptional behavior is best addressed"; I call it "competency point". The detail explanation of this approach need a couple of good code samples, I think it would go a bit beyond of the present question.

Please take a look: I think I fixed my inaccuracy and added some more advice. I would be interested if you share your opinion...

Thank you,
—SA
Matt T Heffron 20-Mar-13 16:00pm    
Better, up to 5.
Sergey Alexandrovich Kryukov 20-Mar-13 16:04pm    
That wasn't my purpose, of course; and I would be grateful for more criticism, but thank you very much.
—AS
If the constructor throws an exception, the assignment doesn't happen because the execution continues where the exception is caught.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 20-Mar-13 15:37pm    
This is correct, but for those who did not understand it in first place, it really needs explanation. What is "execution continues"? This time, I voted 4, too. :)
And now I'm going to improve my own answer; again, thank you for your useful comment.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900