Good morning everyone! Welcome to the Less-Common C# Keywords Tour here at Exception Not Found! My name is Reggie and I'll be your tour guide today. For those of you who are visiting us for the first time, welcome! For those of you who have taken our other tours, welcome back!

A tour guide leads high-school cadets on a tour of Peterson Air Force Base

On this tour, we will be learning about some of the less-known and less-used keywords in the C# programming language. We'll see plenty of examples you can take back with you, and discuss some of the situations and scenarios that might arise from the use of these keywords.

Please stick together as we make our way through the exhibit halls, and please, if you have any questions, feel free to ask them.

I wish someone would have told me we were having high school tours today. I hope Mike changed that display...

OK everyone, if you'll follow me, we can get this tour over with underway!

Modifier Keywords

Let's begin our tour with a few keywords from the Modifier wing; follow me please.

const

First up is the const keyword, which many of you may know already. It marks a variable as being "burned in" or unable to be changed or modified after declaration, known as a "constant". For an example, take a look at this display:

public const int YearFounded = 2015;

As you can see, the YearFounded constant is now declared, and cannot be changed later, just as our museum's founding year cannot be changed. My coworker Kathleen has a few notes she'd like to share with you about the const keyword; you'll find them right at the end of our tour.

readonly

At the next display we can see some examples of the readonly keyword, which marks properties or fields as being unable to change after their class's declaration. This means they can be set in a constructor method, but not later. Here's an example:

class ExceptionNotFound
{
    readonly string _streetAddress = "5434 W Main St.";
    
    void ChangeAddress()
    {
        //_streetAddress = "1234 N Central Ave."
    }
}

Notice the line in the ChangeAddress() method that is commented out. If we were to uncomment that line, we would get a compilation error, as the property _streetAddress is marked readonly and thus cannot be changed except in a constructor.

Let's move right along down the row to the next display!

static

The static keyword marks a member as belonging to a type, not to an instance of that type. It often adorns methods and properties, but can also be used on operators, events, constructors, and other things. Let's see an example:

static class FunnyWords
{
    static string Cow = "Cow";
}

This means that we use the string Cow like this:

do
{
    Console.WriteLine(FunnyWords.Cow);
} while (1 < 2) //Forever

So while const makes a property unable to change at all and readonly makes a property of a class unable to change after the class's declaration, static makes a member belong to a type, not an instance. Easy enough right? Right. Moving right along...

sealed

The sealed keyword marks a class as unable to be derived from. That means that a sealed class does not allow any other classes to inherit from it. Here's our example:

class Animal {}
sealed class Dog : Animal {}

Our class Animal is inherited by class Dog, but nothing else can inherit from Dog. We wouldn't want any werewolves running around, would we? No, we wouldn't.

virtual

In the next two exhibits we will see examples for two closely related keywords. The first is virtual, which some of you may have already used in your programs. virtual means that a particular method or property can be overridden in a derived class.

public class Rectangle
{
    public double length;
    public double width;
    public virtual double Area()
    {
        return length * width;
    }
}

Now, using virtual goes hand-in-hand with using our next keyword, which is just a few steps this way.

override

Whenever a property, method, event, or other item in C# is marked with the virtual keyword, classes which want to implement their own version of that property, method, or whatever use the override keyword to mark their implementation (this also works for methods marked as abstract). The display case to my right contains a simple snippet which builds off the virtual example:

public class Square : Rectangle
{
    public double side;
    public override double Area()
    {
        return side * side;
    }
}

There are a few more examples in this hall, including volatile and unsafe, but in the interest of time and my sanity let's continue on to the next hall. Right this way, please.

Code Structure Keywords

OK, now we can get started with a few examples from our Code Structure wing. To begin, let's.... Excuse me for a moment.

Hey! You two! Get out of that display! Yes, you! I'm looking right at you! Now!

Pardon the interruption. As I was saying, let's see a few examples from our extensive Code Structure wing.

using Directive

I'd be willing to be that many of you have used this keyword before, but how many of you know that it has several more less-known uses? The using directive actually has several contexts where it can be used.

Judging by your rather poorly-hidden groans, I'll refrain from making more puns. You could say I'll be... using more discretion?

OK, OK, that'll be enough puns. For now.

First, when allowing the use of a types in a namespace (most commonly at the beginning of C# files):

using System.Text;
using System.Data;

Secondly, using static allows access to static members of a type:

using static System.Math;

public class Circle
{
    public double Radius;
    public double Circumference()
    {
        return 2 * PI * Radius; //We don't need the Math. prefix to use PI
    }
}

Finally, when creating an alias for a namespace or type:

using MyProject = MyCompany.MyNamespace.MyProject;
using StaceysMom = Has.Got.It.Going.On;

Why you little animals...

Please pardon this display, it appears to have been... tampered with. Let's move quickly on to another example of the using keyword.

using Statement

Gotta come up with some synonyms for "use" real quickly...

While using can be... deployed to those three main scenarios, it also has another common... situation where it can be... employed.

Here's the example:

using (MyContext context = new MyContext) { }

This syntax ensures that objects which implement the interface IDisposable are in fact disposed at the end of the section between the braces. This is particularly useful in programs that use Entity Framework contexts.

Let's see a few more examples of keywords for code structure and how we can... use them efficiently.

break

Dammit, Mike. You didn't change the display. Okay, deep breath, deep breath...

Ahem. You have almost certainly used the break keyword before, but it is good to review it compare against our next example. The break keyword merely stops execution of a loop, like in this display case to my left:

for(int i = 0; i < 100; i++)
{
    if(i == 69)
    {
        break;
    }
}

Quiet please. In this example, the for loop stops when i is equal to 69.

continue

Right next to the break example, and on my right, is the continue keyword. The continue keyword passes the control to the next iteration of the encosing loop...:

int sumOfOddNumbers;
for(int i = 1; i < 100; i++)
{
    if(i % 2 == 0 || i == 69)
    {
        continue;
    }
    sumOfOddNumbers += i;
}

Seriously?

...Just like how we will continue right over to the next display.

goto

Now, you may have heard that this next keyword is the cause of a great many problems in the programming world. I'm here to tell you that's not necessarily true. The goto keyword transfers control to a labeled statement, and though you probably won't use it very much, it is certainly nice to have when you need it.

static void Main()
{
    int x = 100, y = 4;
    int count = 0;
    string[,] array = new string[x, y];

    // Initialize the array:
    for (int i = 0; i < x; i++)
    {
        for (int j = 0; j < y; j++)
        {
            array[i, j] = (++count).ToString();
        }
    }

    // Initialize the number to search for:
    string myNumber = 69;

    // Search:
    for (int i = 0; i < x; i++)
    {
        for (int j = 0; j < y; j++)
        {
            if (array[i, j].Equals(myNumber))
            {
                goto Found;
            }
        }
    }

    Console.WriteLine("The number {0} was not found.", myNumber);
    goto Finish;

Found:
    Console.WriteLine("The number {0} is found.", myNumber);

Finish:
    Console.WriteLine("End of search.");
}

Oh for Pete's sake Mike? This one too?

Ahem. That's enough snickering, you two.

As you can see, once the, um, desired number is found, we immediately end the search since we got what were looking for.

Let's see one last example in the Code Structure wing thank God.

yield

The yield keyword deals with iterators, and solves a specific problem: how do we return each item from a collection individually?

yield is used in two forms: yield return and yield break. The yield return form returns items in an enumerable-collection individually, and yield break stops this iteration. The display case behind you shows an example:

public class PowersOf2
{
    static void Main()
    {
        foreach (int i in Power(2, 20))
        {
            Console.Write("{0} ", i);
        }
    }

    public static System.Collections.Generic.IEnumerable<int> Power(int number, int exponent)
    {
        int result = 1;

        for (int i = 0; i < exponent; i++)
        {
            result = result * number;
            if(result > 5000)
            {
                yield break;
            }
            yield return result;
        }
    }

    // Output: 2 4 8 16 32 64 128 256 512 1024 2048 4096
}

It's important to note that yield is especially designed for iterators, so if you aren't using one, you won't be using yield.

OK! Let's move on to our last stop on this tour, the Hall of Assorted Keywords. Step this way, please, and stick together.

Other Keywords

Here in the Hall of Assorted Keywords we have assembled a few quality examples of other keywords in the C# langu... Excuse me for a second.

Psst. Greg. Greg! Could you check the men's restroom please? I seem to be missing a few people, and if they're doing what I think they're doing the smell never comes out. Thanks.

As I was saying, this Hall contains a few more useful keywords for the C# language. We'll discuss three of them on this tour. Let's start with the display on my right.

params

Sometimes, we need methods to take an arbitrary or variable number of arguments; this is where the params keyword becomes useful. The params keyword allows us to send a comma-separate list of arguments which get combined into a collection. Let's look closely at the example in the display case on the far wall:

public static int SumAll(params int[] numbers)
{
    int sum = 0;
    foreach(var num in numbers)
    {
        sum += num;
    }
    return sum;
}

If you'll follow me to the far wall, we'll take a look at our last two examples on this tour.

dynamic

The dynamic keyword is a dangerous one to use, because it bypasses compile-time checking of types, instead doing that check at runtime. This means that your program might treat a dynamic property as being of type int, but there's no guarantee it actually is an integer; it could be a string. Therefore, use caution when using this keyword.

public string TypeChecker(dynamic d)
{
    if(d is int)
    {
        return "Integer";
    }
    if(d is char)
    {
        return "Char";
    }
    if(d is string)
    {
        return "String";
    }
}

Let's continue on to the next display.

as

Now we come to another keyword you've probably used before: the as keyword. This keyword is used to convert an object to another type, with certain restrictions. For example, the first display shows us how to convert an integer to a double:

public class Parent() { }
public class Child : Parent { }
class Program
{
    static void Main()
    {
        Child firstChild = new Child();
        Parent firstParent = firstChild as Parent;
    }
}

You might notice that this is very similar to casting, with one important difference: if the as keyword fails to convert the type to the target type, it returns null, rather than throwing an exception.

With that, we've finished our tour! Finally!

Summary

Thank you for coming on this tour! To recap, here's the keywords we discussed today:

  • const: Declares a "burned-in" value.
  • readonly: Makes a field read-only.
  • static: Denotes a property of a type, and not an instance of that type.
  • sealed: Denotes a class which cannot be inherted.
  • virtual: Denotes a method or property which can be overridden.
  • override: Denotes an overriding implementation of a virtual or abstract method or property.
  • using: Declares types in namespaces usable in the current file.
  • using static: Allows usage of static members of a class.
  • using clause: Disposes an IDisposable object at the end of the clause.
  • break: Ends the execution of a loop.
  • continue: Ends the current iteration of a loop, starts the next iteration.
  • goto: Transfers control to a named label.
  • yield return: Returns individual items in an enumerable collection.
  • yield break: Stops the iteration over a enumerable collection.
  • params: Allows for an arbitrary number of parameters to a method.
  • dynamic: Allows a property to bypass type checking at runtime.
  • as: Attempts to cast a value to a different types, and returns null if that fails.

Please feel free to stop at the bookstore on your way out; there are quite a few useful books there that'll teach you a bit more about the C# language and keywords. One of my favorites is Professional C# and .NET Core 2.0 by Christian Nagel; check it out if you think you'd like to develop web application with the .NET Framework.

The bus will be here to take you back to school in about thirty minutes; for now, please enjoy the rest of the museum. Have a great rest of your day!

Phew! That could have gone better. Now, where's Mike? Ah. Mike! Would you kindly come here for a second? I need to have a word with you about those displays you seem so fond of...