Title: Throw a standard exception in C#
The example Use try catch blocks to protect against unexpected errors in C# explains how to catch an exception and briefly mentions that you can use the throw statement to throw your own exception. This example shows how to throw standard exceptions in greater detail.
To throw exceptions, use the throw statement passing it a new instance of the exception class that you want to throw. Often the code looks something like the following.
throw new FormatException("Cost must be a monetary amount.");
Replace FormatException with the exception class that you want to throw. The constructors provided by different exception classes take different parameters. Most of them let you pass in a message that is included in the exception object and that the program can show to the user. You should make this message as specific as possible so the user has a chance to fix the problem. For example, say "Cost must be a monetary amount" not "Format error."
Some exception classes may let you pass other values into their constructors such as the name of the parameter causing the problem and the parameter's value.
In this example, when you enter a cost and tip percentage and click Calculate, the following code executes.
// Calculate the tip.
private void btnCalculate_Click(object sender, EventArgs e)
{
try
{
PerformCalculation();
}
catch (Exception ex)
{
txtTipAmount.Clear();
MessageBox.Show(ex.Message);
}
}
private void PerformCalculation()
{
// Parse the cost.
decimal cost;
if (!decimal.TryParse(txtCost.Text,
NumberStyles.Currency, null, out cost))
throw new FormatException("Cost must be a monetary amount.");
// Validate the cost.
if ((cost < 0.01m) || (cost > 500m))
throw new ArgumentOutOfRangeException(
"Cost must be between $0.01 and $500.00.");
// Parse the tip percentage.
string percent_string = txtPercentTip.Text;
if (percent_string.StartsWith("%"))
percent_string = percent_string.Substring(1);
else if (percent_string.EndsWith("%"))
percent_string = percent_string.Substring(
0, percent_string.Length - 1);
decimal tip_percent;
if (!decimal.TryParse(percent_string, out tip_percent))
throw new FormatException("% Tip must be a numeric value.");
// If the original value contained a % symbol, divide by 100.
if (txtPercentTip.Text.Contains("%")) tip_percent /= 100m;
// Validate the percentage.
if ((tip_percent < 0) || (tip_percent > 100))
throw new ArgumentOutOfRangeException(
"% Tip must be between 0% and 100%.");
// Everything's valid. Perform the calculation.
decimal tip_amount = cost * tip_percent;
txtTipAmount.Text = tip_amount.ToString("C");
}
The button's Click event handler uses a try catch block to protect itself when it calls the PerformCalculation method, which does all of the interesting work.
The PerformCalculation method attempts to parse the cost value that you entered and, if it fails, throws a FormatException to tell you that the cost is invalid. If the cost parses, then the code validates its value and throws an ArgumentOutOfRangeException if the value is too big or too small.
The code then performs similar validations for the tip percent value.
Whenever the code encounters a problem that it can't fix, it throws an exception to tell the calling code what happened. In this simple example, you could put code in the PerformCalculation method to display error messages, although that would make the code more complicated and a bit messier. This technique is much more important when your code is called by someone else's code. In that case you may not know what action the calling code should take in response to various errors, so the exception classes tell the calling code what went wrong.
For some of the calculations, you could just let the program fail. For example, you could try to use decimal.Parse to parse the numeric values and let decimal.Parse throw an exception if it fails. That tells the calling code in general what went wrong, but it doesn't give any context that the code can use to help the user. This example throws its own exceptions so it can provide better error messages that tell the user what went wrong. For example, it tells the user "Cost must be a monetary amount" rather than just saying "Input string was not in a correct format."
Download the example to experiment with it and to see additional details.
|