问题
I'll try and ask my question so it doesn't end as a simple argumentative thread.
I've jumped into an application coded in C# recently and I'm discovering the exception mechanism. And I've had a few bad experiences with them such as the following
// _sValue is a string
try
{
return float.Parse(_sValue);
}
catch
{
return 0;
}
I changed it into :
float l_fParsedValue = 0.0f;
if (float.TryParse(_sValue, out l_fParsedValue))
{
return l_fParsedValue;
}
else
{
return 0;
}
Result, my Output in Visual Studio is not anymore flooded with message like
First chance System.FormatException blabla
when string like '-' arrive in the snippet. I think it's cleaner to use the second snippet.
Going a step further, I've often seen that exceptions are too often used ilke: "I do whatever I want in this try-catch, if anything goes wrong, catch.".
Now in order to not get stuck with bad misconceptions, I would like you guys to help me clearly define how/when to use those exceptions and when to stick with old school "if...else".
Thanks in advance for your help!
回答1:
You should throw exception in exceptional cases. i.e. when something unexpected happens. If you expect a function to regularly throw an exception that's most likely bad design.
In your examples it is very clear that TryParse
is better since the exception seems to occor often.
But for example when parsing a file, I expect it to be almost always valid. So I usually use Parse
and catch the exception and generate a InvalidDataException
with the caught exception as inner exception. Usually simplifies the parsing code a lot, even if it may be bad style.
I recommend Eric Lippers's blog entry: Vexing exceptions
回答2:
In case of Parse()
/TryParse()
it's better don't wait for exception, use TryParse and act on incorrect input by yourself.
回答3:
Exceptions should be used for exceptional behavior, not for flow-control. A basic guideline would be that if normal program flow regularly runs into exceptions you're doing something wrong.
However, it is important to notice that just having a try { } catch { }
present will itself not affect performance negatively. Only when an exception is actually thrown and the stack trace needs to be computed you will see (in some cases quite severe) performance degradation.
回答4:
Another point that hasn't been examined in depth so far is that Exceptions have a cost. They subvert the normal flow of control in the program and there is some resource use as a result.
A simple test would be to write a program that loops over your original float.Parse code with some invalid data, and compare how long it takes to run versus the TryParse version - there will be a small but noticeable difference.
A snippet that sticks in my mind when making decisions about exceptions is from this article:
Almost Rule #1
When deciding if you should throw an exception, pretend that the throw statement makes the computer beep 3 times, and sleep for 2 seconds. If you still want to throw under those circumstances, go for it.
回答5:
Programs that use exceptions as part of their normal processing suffer from all the readability and maintainability problems of classic spaghetti code.
— Andy Hunt and Dave Thomas
I think there is no simple right answer about how/when to use exceptions. It depends on an architecture of the application you're working on and other factors.
I can suggest you to read the chapters 8.3. Error-Handling Techniques and 8.4. Exceptions of the Code Complete book.
回答6:
Ahh, if only it was that simple! But, alas - the decision when to use exceptions is more often subjective than not. Still, there are guidelines you can use. For example, Microsoft has some.
All in all, the rule of thumb for throwing exceptions is - you only throw an exception when a function cannot do what it was supposed to do. Basically each function has a contract - it has a legal range of input values and a legal range of output values. When the input values are invalid, or it cannot provide the expected output values, you should throw an exception.
Note that there is a slippery point here - should validation (of user input) errors also be thrown as exceptions? Some schools of thought say no (Microsoft included), some say yes. Your call. Each approach has its benefits and drawbacks, and it's up to you to decide how you will structure your code.
A rule of thumb for catching exceptions is - you should only catch exceptions that you can handle. Now, this is also slippery. Is displaying the error message to the user also "handling" it? But what if it's the infamous StackOverflowException
or OutOfMemoryException
? You can hardly display anything then. And those might not be the only exceptions that can leave the whole system in an unusable state. So again - your call.
来源:https://stackoverflow.com/questions/6184676/exceptions-when-to-use-timing-overall-use