22

Following examples in my C# book and I came across a book example that doesn't work in Visual Studio. It deals with creating your own exceptions, this one in particular is to stop you from taking the square root of a negative number. But when I create the NegativeNumberException by using "throw new" I get an error that says "The type or namespace name 'NegativeNumberException' could not be found (are you missing a using directive or an assembly reference?)"

How can I create my own exceptions if this isn't the right way? Maybe my book is outdated? Here's the code:

class SquareRootTest
{
    static void Main(string[] args)
    {
        bool continueLoop = true;

        do
        {
            try
            {
                Console.Write("Enter a value to calculate the sqrt of: ");
                double inputValue = Convert.ToDouble(Console.ReadLine());
                double result = SquareRoot(inputValue);

                Console.WriteLine("The sqrt of {0} is {1:F6)\n", inputValue, result);
                continueLoop = false;
            }
            catch (FormatException formatException)
            {
                Console.WriteLine("\n" + formatException.Message);
                Console.WriteLine("Enter a double value, doofus.\n");
            }
            catch (NegativeNumberException negativeNumberException)
            {
                Console.WriteLine("\n" + negativeNumberException.Message);
                Console.WriteLine("Enter a non-negative value, doofus.\n");
            }
        } while (continueLoop);
    }//end main
    public static double SquareRoot(double value)
    {
        if (value < 0)
            throw new NegativeNumberException(
                "Square root of negative number not permitted.");
        else
            return Math.Sqrt(value);
    }
}
Evan Lemmons
  • 807
  • 3
  • 11
  • 27
  • 3
    You need to actually create the class "NegativeNumberException", which will derive from System.Exception. You can't just put class names there to create things. – Pierre-Luc Pineault Dec 05 '13 at 04:14

4 Answers4

54

Exception is just a class like many other classes in .Net. There're, IMHO, two tricky things with user defined exceptions:

  1. Inherit your exception class from Exception, not from obsolete ApplicationException
  2. User defined exception should have many constructors - 4 in the typical case

Something like that:

public class NegativeNumberException: Exception {
  /// <summary>
  /// Just create the exception
  /// </summary>
  public NegativeNumberException()
    : base() {
  }

  /// <summary>
  /// Create the exception with description
  /// </summary>
  /// <param name="message">Exception description</param>
  public NegativeNumberException(String message)
    : base(message) {
  }

  /// <summary>
  /// Create the exception with description and inner cause
  /// </summary>
  /// <param name="message">Exception description</param>
  /// <param name="innerException">Exception inner cause</param>
  public NegativeNumberException(String message, Exception innerException)
    : base(message, innerException) {
  }

  /// <summary>
  /// Create the exception from serialized data.
  /// Usual scenario is when exception is occured somewhere on the remote workstation
  /// and we have to re-create/re-throw the exception on the local machine
  /// </summary>
  /// <param name="info">Serialization info</param>
  /// <param name="context">Serialization context</param>
  protected NegativeNumberException(SerializationInfo info, StreamingContext context)
    : base(info, context) {
  }
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • For some reason I had to change each `String` type to `string` or I got the error: `'String': static types cannot be used as parameters`. –  Mar 13 '16 at 20:22
  • 2
    @kill4silence: add `using System;` since `String` in an *alias* of `string` has been defined in the `System` namespace. – Dmitry Bychenko Mar 14 '16 at 06:38
  • @JamesM This could be if you have a static class called String...maybe for Extension-methods.? – Nikolaus May 07 '19 at 21:11
5

All exceptions are types just like any other, and if you want to define a custom type of exception, you actually have to make a class for it:

/* You could also use ArgumentException, etc. */
class NegativeNumberException : Exception {
    …
}

…
Ry-
  • 218,210
  • 55
  • 464
  • 476
  • [It's generally recommend to derive any custom exception types from `Exception`, and to specifically avoid `ApplicationException`](http://msdn.microsoft.com/en-us/library/seyhszts(v=vs.110).aspx), but it this case I don't know why you wouldn't just throw the out of the box `ArgumentException`. – Preston Guillot Dec 05 '13 at 04:24
  • @PrestonGuillot: Huh, thanks. These best practices, always changing… – Ry- Dec 05 '13 at 04:26
3

Since .NET 3.0 custom exceptions should be derived from Exception and not ApplicationException, so use this:

public class NegativeNumberException : Exception
{ 
    public NegativeNumberException():base() { } 
    public NegativeNumberException (string message): base(message) { }
}
swandog
  • 741
  • 8
  • 22
1

You need to declare your custom Exception NegativeNumberException class.

all custom Exception are child classes of Exception so derive NegativeNumberException class from Exception class

From MSDN :

If you are designing an application that needs to create its own exceptions, you are advised to derive custom exceptions from the Exception class. It was originally thought that custom exceptions should derive from the ApplicationException class; however in practice this has not been found to add significant value. For more information, see Best Practices for Handling Exceptions. ApplicationException uses the HRESULT COR_E_APPLICATION, which has the value 0x80131600.

Try This:

 public class NegativeNumberException : Exception
        {         


           public NegativeNumberException():base()
            {


            }   

            public NegativeNumberException (string message): base(message)
            {


            }


        }
Sudhakar Tillapudi
  • 25,935
  • 5
  • 37
  • 67