a question about exception in c#
Asked Answered
N

7

-1

following is a code snippet:

class xxx
{

  public xxx(){}

  try
  {
    throw new Exception(InvalidoperationException);
  }
  catch(Exception x)
  {
  }
  catch(InvalidoperationException x)
  {
  }
}

can anyone tell which exception will raise here and what is the reason behind it.

Nonlegal answered 7/5, 2011 at 8:26 Comment(1)
"following is a code snippet" - not one that compiles.Brusa
D
8

Wow, lots of problems here. Where to start?

  1. That code won't compile. The try-catch block that you've defined is outside of any method, which is not allowed. You need to move it inside of a method.

  2. Never throw a method that you intend to catch yourself later in the method. That's commonly known as using exceptions for "flow control", which is roundly discouraged. There is a performance cost associated with doing so, and it also makes it very confusing to monitor the exceptions that are being thrown when using a debugger when you have code that's throwing and catching it's own exceptions. Use boolean variables (known as flags) for flow control, if necessary.

  3. Always catch the most derived exception class first. That means you should catch InvalidOperationException first, before trying to catch Exception. You need to reverse the order of your catch blocks in the code that you have.

  4. You should practically never catch System.Exception. The only exceptions that you should catch are those that you explicitly understand and are going to be able to handle. There's virtually no way that you're going to know what went wrong or how to handle it when the only information you have is that a generic exception was thrown.

    Along those same lines, you also should never throw this exception from your own code. Choose a more descriptive exception class that inherits from the base System.Exception class, or create your own by inheriting from the same.


I see that other answers are showing you sample code of what your code should look like, were it to be rewritten. I'm not going to do that because if I rewrote your code to be correct, I'd end up with this:

class Xxx
{
    public Xxx()
    {

    }
}

Not particularly helpful.

Disputatious answered 7/5, 2011 at 8:39 Comment(3)
The performance cost (when not using a debugger) is generally over-stated; however, I agree it is still not a good idea. I disagree with the "never catch System.Exception; for example, "log and rethrow", or a few other scenarios it isn't unreasonable.Aristaeus
@Marc: There are almost always better ways to log unhandled exceptions than catching and rethrowing. For WinForms, the AppDomain.UnhandledException is a great place to start. I'm not much for blanket statements either, but in almost every case I see code catching System.Exception, it's wrong. And you certainly shouldn't catch System.Exception anywhere but a top-level exception handler. That's not what the above code demonstrates.Disputatious
if you hit UnhandledException, your app is toast; and there are a number of exceptions that don't hit this - of course, they're pretty severe anyway, so probably uncatchable via any route.Aristaeus
M
2

If the code is like this

 class xxx
    {

      public xxx(){

      try
      {
        throw new Exception(InvalidoperationException);
      }

      catch(InvalidoperationException x)
      {
      }

catch(Exception x) { } } }

It should compile and raise your exception and catch. Otherwise your code will not compile at all.

Meadors answered 7/5, 2011 at 8:35 Comment(2)
Which logic is this ? It would never compile.Guileful
yeah it will not compile, as the "Exception" class should be at end of any other classes. ThanksMeadors
R
1

No exception will be thrown as this code will not even compile.

Regardless - several points:

  • When using exception handling, put the more specific exception before the less specific ones (so the catch of InvalidOperationException should be before the one for Exception).
  • Catching Exception is normally no very useful.
  • If you catch an exception, do something with it.

You probably meant:

throw new InvalidOperationException();

However, the way you structured your exceptions, the catch(Exception x) block would have run.

Reitz answered 7/5, 2011 at 8:29 Comment(0)
M
1

You should write:

class xxx
{
    public void Test()
    {
        try
        {
          throw new InvalidoperationException(); 
        }
        catch(InvalidoperationException exception)
        {
            // Do smth with exception;
        }            
        catch(Exception exception)
        {
            throw; // Rethrows your exception;
        }
    } 
}

InvalidOperationException inherits from Exception. catch tries to processes the most specific branch, so catch (InvalidOperationException x) will be executed here.

Medicate answered 7/5, 2011 at 8:34 Comment(1)
You should also reorder the catch blocks - the first block that matches will run, not the most specific (since all exceptions inherit from Exception).Reitz
G
1

Nope. It wouldn't compile. So, it there's no question about as to which exception will be generated.

Your code should be something like this :

class xxx
{
    public void Test()
    {
        try
        {
          throw new InvalidoperationException(); 
        }
        catch(InvalidoperationException exception)
        {
            // Something about InvalidOperationException;
        }            
        catch(Exception exception)
        {
            // Something about the Exception
        }
    } 
}

Point to be noted :

  1. Write more specific class of Exception first, hence we write InvalidOperationException prior to Exception class.
Guileful answered 7/5, 2011 at 8:37 Comment(0)
A
0

Ignoring the compile issue.... the first matching exception block (catch(Exception x)) will get the exception. You then ignore the exception and don't re-throw, so exception will be seen by the outside world. That doesn't make it good practice, though... in particular, catching an arbitrary Exception and ignoring it is risky - it could have been anything... it isn't necessarily the exception you thought it was.

Aristaeus answered 7/5, 2011 at 8:40 Comment(0)
B
0

Well, the code won't compile, but I'll just ignore that...

If I'll just look at the line:

throw new Exception(InvalidoperationException);

1st of all, according to MSDN there is no such constructor. So I will assume you meant the constructor: Exception(String msg, Exception innerException). Meaning: throw new Exception("blabla", InvalidoperationException);

The exception that is being thrown is of type Exception and not InvalidOperationException. So ONLY catch(Exception x) can catch it.

If you would've thrown InvalidoperationException than the way you wrote the order of the catches, the Exception class would get caught first. The order of the catches does matter.

The best advice I can give you is simply try it yourself and see what happens.

Blaze answered 7/5, 2011 at 8:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.