Based on what I've learned at Wonderland so far, Infinity was the visible leader of the base, but it appeared that there was a commander above her calling the shots. Being inherently curious, I decided to ask Infinity about it directly rather than trying to figure it out on my own. I met her in the kitchen getting coffee one day, as usual.
"Hi Infinity, how are you?" I started the conversation.
"Hi Teo, I'm doing well, thank you," She replied, continuing, "And you?"
"I'm fine, thanks. Can I ask you something? Who's the ultimate head of
Wonderland? I thought I heard you receiving orders the other day from
someone. Was I hearing right? I thought you were the leader of the
resistance in Wonderland."
"Ritchie warned me that you like to eavesdrop," she said, sighing.
"I'm not sure I would say I 'like' it," I said, trying to excuse my way out.
"I would say that it happens sometimes, not that I..."
Infinity cut me off before I could make more of a fool of myself. "I trust you, Teo. You helped me rescue my sister - I'll never forget that. Now listen. This doesn't go beyond this room. The actual decision makers at Wonderland are a mystery to everyone. Even I don't know who the 'real boss' is. I get all orders from a person I've been instructed to just call Commander. He's refused to answer any of my prying questions, probably for the sake of security. Once a month I have a conference call with him, where he gives me direct orders. I've never seen him. I don't even know where he's located. We just execute his commands and report back to him next time."
"How can you be sure that Commander has our best interest in mind? What if we can't trust him, or if it would be better for us to operate independently?" I asked.
"He was leading Wonderland long before I joined the resistance. In fact, to the best of anyone's knowledge, he was one of the original founders of Wonderland. For now, the system works this way and we'll keep it unchanged unless we find a better option," Infinity explained.
Hmm... something in her response seemed familiar to me, but I couldn't remember why exactly. "To keep the system unchanged." Where had I heard that before?
The next topic on the Wonderland curriculim was Exceptions . I'd heard about these before, but never in depth. We had programmed in a console output of "Exception has been thrown..." a couple of times, and now it was time to learn exactly what that meant.
"Hello everyone," Sintia started the lesson, "Can anyone tell me what types
of errors C# program have?"
"Runtime and compile-time errors!" Someone answered.
"Right. And the difference between those two is?" Sintia was asking more
than telling today.
"Compile-time errors happen when the code is translated to IL code, runtime
errors happen when the program is executed," I answered.
"Excellent! To make sure that you didn't just memorize that... Is a missed
semicolon a runtime or a compile-time error?" Sintia asked once again.
"Compile-time," someone from the class answered.
"That's also correct. Now, can you name some runtime errors?"
"Division by zero, NullReferenceException... " I answered, trying to think
of others.
"I don't think we've discussed NullReferenceException, but you are right,
together with division by zero, those are both runtime errors. Does anyone
know how C# lets you know about runtime errors?"
Nobody answered; she had finally reached the edge of our knowledge on the
subject.
"In most cases, it happens through
exceptions
.
An exception is a mechanism that is used to indicate a runtime error in
the program.
In C#, exceptions are represented by objects of a class Exception, or
classes derived from it.
"
"Sintia, what is a derived class?" Someone asked.
"For now, consider derived classes as you do classes; they both have similar
functionality," Sintia said. "We'll learn about derived classes in-depth at
a later time."
"
To throw an exception, you can either use the keyword
throw
with a generated object of type Exception, or trigger one of the standard
compiler-generated exceptions.
Here is an example:"
var a = 12;
var b = 0;
var c = a / b; // Throws DivideByZeroException. Compiler-generated
string name = null;
var length = name.Length; // Throws NullReferenceExceprion. Compiler-generated
throw new Exception("My exception"); // Throws Exception. Generated by
// a programmer
"Sintia, I still don't get it. What do these exceptions look like in practice? As a programmer or a user of a program, how would I understand that the program has thrown an exception? When I get compile-time errors, they are usually depicted in the output window of my IDE (Visual Studio)," said one of the students. I felt the same; exceptions would be of little use if they weren't clear to the programmer or the user of the program.
"I understand your question," Sintia said, turning her attention to her tablet. After a few swipes, we saw two projected images that showed what an exception would look like from a programmer's perspective.
"Now it makes perfect sense!" I exclaimed and continued, "I've seen this error message many times, but didn't understand it at the time. So every time I saw it, there was an exception thrown somewhere in my code? How do I know what type the exception has, and where it was thrown? " I asked.
" Visual Studio tells you both of those answers. It shows the type of exception and the line number in the code from where it was thrown ," Sintia explained. "For now, let's move on and see how the user experiences an exception. Here is the code of my program:"
var a = 12;
var b = 0;
Console.WriteLine("Hello, let's divide by zero!");
var c = a / b;
Console.WriteLine($"The result is {c}");
"And on the other screen, you can see the screenshot of this program running."
"As you see, at first the program executed in normal order, and console
output
Hello, let's divide by zero!
Then the program crashed, throwing an exception
DivideByZeroException
. Execution of the code stopped and the program subsequently terminated."
"Sintia, does an exception
always
terminate the program in which it appears?" I asked.
"No,
C# has a mechanism to handle exceptions, called a
try-catch
. It allows you to catch exceptions and handle the error before it causes a
crash. Look at this code snippet," Sintia replied, projecting a new code
snippet on the wall.
var a = 12;
var b = 0;
Console.WriteLine("Hello, let's divide by zero!");
try
{
var c = a / b;
Console.WriteLine($"The result is {c}");
}
catch (DivideByZeroException ex)
{
Console.WriteLine("There was an attempt to divide by zero!");
}
Console.WriteLine("I'm still running!");
// Outputs:
// Hello, let's divide by zero!
// There was an attempt to divide by zero!
// I'm still running!
" To handle an exception, surround the code that throws an exception with a try {} block followed by a catch {} block. The code that handles the exception lives in the catch block, and the code that throws an exception lives in the try block. If you omit the parenthesis after the catch block, as in the following example, it will catch exceptions of any type: "
try
{
throw new ArgumentException();
}
catch // If nothing here, it cathches exceptions of all types
{
Console.WriteLine("An exception was thrown, I'm not sure which one though.");
}
// Outputs
// An exception was thrown, I'm not sure which one though.
"To catch exceptions of a specific type, specify that type immediately after
the
catch
block," Sintia explained.
try
{
throw new ArgumentException();
}
catch (DivideByZeroException ex) // Catches only DivideByZeroException
{
Console.WriteLine("DivideByZeroException was thrown.");
}
// Outputs nothing
try
{
throw new DivideByZeroException();
}
catch (DivideByZeroException ex) // Catches only DivideByZeroException
{
Console.WriteLine("DivideByZeroException was thrown.");
}
// Outputs
// DivideByZeroException was thrown.
"You can supply a message to explain exactly what went wrong. Put this message in the constructor of an exception that you throw. To access this message in the catch block, add a variable name inside the parenthesis and use its property Message , like this:"
try
{
throw new Exception("Something broke!"); // Specify a message here
}
catch (Exception ex) // A variable ex now represents the exception that
// was thrown
{
Console.WriteLine($"Exception was thrown: {ex.Message}");
}
// Outputs
// Exception was thrown: Something broke!
"Sintia, when you showed an exception from the user perspective, it stated "an unhandled exception" . What is this? What is the difference between handled and unhandled exceptions?" asked one of the students.
"Oh, that's pretty straightforward. If you have a
try-catch
construction that handles an exception, it's considered to be
handled
. In all other cases, the exception is considered to be unhandled.
If an unhandled exception occurs, the program is terminated by the
operating system,
" she explained.
"For more information, you can study a
not complete list of C# exceptions
. Now it is time for some exceptional tasks!"