C# Questions on Exception Handling
1 Can I use exceptions in C#?
Yes, in fact exceptions are the recommended error-handling mechanism in C# (and in .NET in general). Most of the .NET framework classes use exceptions to signal errors.
2 What types of object can I throw as exceptions?
Only instances of the System.Exception classes, or classes derived from System.Exception. This is in sharp contrast with C++ where instances of almost any type can be thrown.
3 Can I define my own exceptions?
Yes, just derive your exception class from Application.Exception.
4 Does the System.Exception class have any cool features?
Yes - the feature which stands out is the StackTrace property. This provides a call stack which records where the exception was thrown from. For example, the following code:
using System;
class CApp
{
public static void Main()
{
try
{
f();
}
catch( Exception e )
{
Console.WriteLine( "System.Exception stack trace = \n{0}", e.StackTrace );
}
}
static void f()
{
throw new Exception( "f went pear-shaped" );
}
}
produces this output:
System.Exception stack trace =
at CApp.f()
at CApp.Main()
Note, however, that this stack trace was produced from a debug build. A release build may optimise away some of the method calls which could mean that the call stack isn't quite what you expect.
5 When should I throw an exception?
This is the subject of some debate, and is partly a matter of taste. However, it is accepted by many that exceptions should be thrown only when an 'unexpected' error occurs. How do you decide if an error is expected or unexpected? This is a judgement call, but a straightforward example of an expected error is failing to read from a file because the seek pointer is at the end of the file, whereas an example of an unexpected error is failing to allocate memory from the heap.
6 Does C# have a 'throws' clause?
No, unlike Java, C# does not require (or even allow) the developer to specify the exceptions that a method can throw.
Run-time Type Information
7 How can I check the type of an object at runtime?
You can use the is keyword. For example:
using System;
class CApp
{
public static void Main()
{
string s = "fred";
long i = 10;
Console.WriteLine( "{0} is {1}an integer", s, (IsInteger(s) ? "" : "not ") );
Console.WriteLine( "{0} is {1}an integer", i, (IsInteger(i) ? "" : "not ") );
}
static bool IsInteger( object obj )
{
if( obj is int obj is long )
return true;
else
return false;
}
}
produces the output:
fred is not an integer
10 is an integer
8 Can I get the name of a type at runtime?
Yes, use the GetType method of the object class (which all types inherit from). For example:
using System;
class CTest
{
class CApp
{
public static void Main()
{
long i = 10;
CTest ctest = new CTest();
DisplayTypeInfo( ctest );
DisplayTypeInfo( i );
}
static void DisplayTypeInfo( object obj )
{
Console.WriteLine( "Type name = {0}, full type name = {1}", obj.GetType(), obj.GetType().FullName );
}
}
}
produces the following output:
Type name = CTest, full type name = CTest
Type name = Int64, full type name = System.Int64
1 Can I use exceptions in C#?
Yes, in fact exceptions are the recommended error-handling mechanism in C# (and in .NET in general). Most of the .NET framework classes use exceptions to signal errors.
2 What types of object can I throw as exceptions?
Only instances of the System.Exception classes, or classes derived from System.Exception. This is in sharp contrast with C++ where instances of almost any type can be thrown.
3 Can I define my own exceptions?
Yes, just derive your exception class from Application.Exception.
4 Does the System.Exception class have any cool features?
Yes - the feature which stands out is the StackTrace property. This provides a call stack which records where the exception was thrown from. For example, the following code:
using System;
class CApp
{
public static void Main()
{
try
{
f();
}
catch( Exception e )
{
Console.WriteLine( "System.Exception stack trace = \n{0}", e.StackTrace );
}
}
static void f()
{
throw new Exception( "f went pear-shaped" );
}
}
produces this output:
System.Exception stack trace =
at CApp.f()
at CApp.Main()
Note, however, that this stack trace was produced from a debug build. A release build may optimise away some of the method calls which could mean that the call stack isn't quite what you expect.
5 When should I throw an exception?
This is the subject of some debate, and is partly a matter of taste. However, it is accepted by many that exceptions should be thrown only when an 'unexpected' error occurs. How do you decide if an error is expected or unexpected? This is a judgement call, but a straightforward example of an expected error is failing to read from a file because the seek pointer is at the end of the file, whereas an example of an unexpected error is failing to allocate memory from the heap.
6 Does C# have a 'throws' clause?
No, unlike Java, C# does not require (or even allow) the developer to specify the exceptions that a method can throw.
Run-time Type Information
7 How can I check the type of an object at runtime?
You can use the is keyword. For example:
using System;
class CApp
{
public static void Main()
{
string s = "fred";
long i = 10;
Console.WriteLine( "{0} is {1}an integer", s, (IsInteger(s) ? "" : "not ") );
Console.WriteLine( "{0} is {1}an integer", i, (IsInteger(i) ? "" : "not ") );
}
static bool IsInteger( object obj )
{
if( obj is int obj is long )
return true;
else
return false;
}
}
produces the output:
fred is not an integer
10 is an integer
8 Can I get the name of a type at runtime?
Yes, use the GetType method of the object class (which all types inherit from). For example:
using System;
class CTest
{
class CApp
{
public static void Main()
{
long i = 10;
CTest ctest = new CTest();
DisplayTypeInfo( ctest );
DisplayTypeInfo( i );
}
static void DisplayTypeInfo( object obj )
{
Console.WriteLine( "Type name = {0}, full type name = {1}", obj.GetType(), obj.GetType().FullName );
}
}
}
produces the following output:
Type name = CTest, full type name = CTest
Type name = Int64, full type name = System.Int64