In this .NET programming tutorial, developers will learn how to deal with non-CLS exceptions in .NET. First, for the uninformed, an exception is an error that occurs during application execution. Typically, exceptions are caught using a Try-Catch block, as demonstrated in the following code example:
using System; class OJExceptionTest { public static void Main() { int numberOne = 0; try { int numberTwo = 100 / numberOne; } catch (ArithmeticException ex1) { Console.WriteLine($"ArithmeticException Output: {ex1}"); } catch (Exception ex2) { Console.WriteLine($"Generic Exception Output: {ex2}"); } } }
In the above example, an integer variable named numberOne was created and initialised to 0. Inside the Try block, a new variable named numberTwo tried to divide 100 by 0. Because it is impossible to divide any number by 0, an ArithmeticException Catch catches this exception, specifically. Below the ArithmeticException Catch block, a general Exception Catch block will be called when any other error occurs.
It is considered good practice to catch specific exceptions, instead of only using a generic exception handler. The output of the above code would like the following:
ArithmeticException Output: System.DivideByZeroException: Attempted to divide by zero. at OJExceptionTest.Main()
Read: C# Tools for Code Quality
How to Deal with non-CLS Exceptions in .NET
Non-CLS exceptions, or non-exceptions, are exceptions that do not derive from Exception. .NET does not allow developers to throw non-exceptions; however, .NET does allow programmers to catch them.
These types of exceptions can be caught (and handled) in two ways. First, by using the RuntimeWrappedException within a catch block. RuntimeWrappedException wraps an exception that does not derive from the Exception class.
An example follows. This code example uses C# and calls the C++/CLI library:
var exampleClass = new CLibraryClass.ClassName(); try { exampleClass.ThrowNonException(); } catch (RuntimeWrappedException e) { String s = e.WrappedException as String; if (s != null) { Console.WriteLine(s); } }
In the above code, we reference a class from a C++/CLI library, then throw an exception from that class in order to make use of RuntimeWrappedException to catch the exception inside the C++/CLI class.
Another example follows, this time using a bit of C++ code to handle the exception:
using namespace System; using namespace System::Runtime::CompilerServices; [assembly:RuntimeCompatibilityAttribute(WrapNonExceptionThrows = true)]; void TryToCatchException() { try { throw gcnew String("Test string"); } catch(RuntimeWrappedException^ e) { Console::WriteLine("RuntimeWrappedException!"); } } int main() { TryToCatchException(); return 0; }
General Catch Blocks in .NET and C#
The second way to deal with these types of errors is to make use of a general catch block without an exception type specified, which is placed after all other catch blocks. This is demonstrated in the following C# code example:
var exampleClass = new CLibraryClass.ClassName(); try { exampleClass.ThrowNonException(); } catch () { //The non-Exception will be caught here }
Read more .NET programming tutorials and software development guides.