Author avatar

Dániel Szabó

Type and Namespace Aliasing for C#

Dániel Szabó

  • Dec 2, 2019
  • 7 Min read
  • 28 Views
  • Dec 2, 2019
  • 7 Min read
  • 28 Views
Languages Frameworks and Tools
C#

Introduction

Namespaces in C# serve two main purposes: to organize classes and functionality and to control the scope of classes and methods. Type aliasing is a little known feature for C# and it comes in handy when you would like to alias a specific method or class from a namespace for the sake of clarity. At the heart of these features is the using keyword.

This guide will teach you how to utilize aliasing properly and make your code or application easy to read and flexible to changes over time.

Using

The using keyword in C# has three major use cases. In the first use case, you define a scope, at the end of which an object is disposed. In the second use case, you create an alias for a namespace or import specific types from other namespaces. In the third use case, you import members of a single class with the static directive.

You might use this keyword when you start out with C# programming. People usually learn how to interact with the console, write out some strings, or read the output. Most of this functionality comes from the System.Console namespace.

Aliasing

Here is a common example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;

namespace scopesandaliases
{   
    class Program
    {
       
        static void Main(string[] args)
        {
            Console.WriteLine("I'm coming from the System namespace");
            Console.Write("Say something nice:");
            var said = Console.ReadLine();
            Console.WriteLine($"You said: {said}");
            Console.ReadKey();
            }
    }
}
csharp

The output looks like this if you say: Say what?

1
2
3
I'm coming from the System namespace
Say something nice:Say what?
You said: Say what?
bash

What happens here? Your first using statement on the top of the app tells the compiler you need everything from the System namespace. This way, you can refer to the WriteLine, Write, and ReadLine functions with the Console. prefix. If you want, you can go further and deeper by modifying your script. You can create an alias for the class Console and alias it with using.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using C = System.Console;

namespace scopesandaliases
{   
    class Program
    {
       
        static void Main(string[] args)
        {
            C.WriteLine("I'm coming from the System namespace");
            C.Write("Say something nice:");
            var said = C.ReadLine();
            C.WriteLine($"You said: {said}");
            System.Console.WriteLine("This is still working!");
            C.ReadKey();            
            }
    }
}
csharp

The output looks like this, after you reply: Aliasing classes are fun, too.

1
2
3
4
I'm coming from the System namespace
Say something nice:Aliasing classes are fun, too.
You said: Aliasing classes are fun, too.
This is still working!
bash

The basic functionality stays the same. Note how the fully qualified System.Console.WriteLine is still accessible to your application, since you can reference the classes and methods with their fully qualified names, despite the aliasing. It adds extra functionality by allowing the developer to code faster and more efficiently due to shorter access to functionality in the namespace. It does not impact the speed of development in a negative way.

Here is another example with the Math class. As mentioned previously in the three use cases for aliasing, one is to pull out a reference from a class to static members and alias them. In the Math class, you have two static members: E and PI. If you want to reference them without the using alias, you need to use the fully qualified name like System.Math.E or System.Math.PI.

Let's create a shorter version with the using static keyword.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using static System.Math;
using System;

namespace scopesandaliases
{   
    class Program
    {
       
        static void Main(string[] args)
        {
            Console.WriteLine($"The value of E is: {E}");
            Console.WriteLine($"The value of PI is: {PI}");
            Console.ReadKey();
        }
    }
}
csharp

The output looks like this:

1
2
The value of E is: 2.71828182845905
The value of PI is: 3.14159265358979
bash

Imagine an application referencing PI or E multiple times throughout. This technique not only saves time, but also makes the code easier to read.

Another common use case for the using keyword is manipulating files or network-related objects. Let's see an example where you write some text to a file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using SW = System.IO.StreamWriter;
namespace scopesandaliases
{   
    class Program
    {
       
        static void Main(string[] args)
        {
            string[] linesToWrite = { "Written", "Guides", "Are", "Really", "Cool!" };

            using (SW myFile = new SW(@"C:\Temp\MyFile.txt"))
            {
                foreach(string line in linesToWrite)
                {
                    myFile.WriteLine(line);
                }
            }
                Console.ReadKey();
        }
    }
}
csharp

The output of this application is a file called MyFile.txt, which holds the following content:

1
2
3
4
5
Written
Guides
Are
Really
Cool!
bash

Let's look at what happens here. You created an alias for the System.IO.StreamWriter class called SW. You have a string array holding five items. The using block is used to write out these items to the file, one item at a time. You could have aliased the FileStream also, but the difference would be that it writes bytes to the output, while the StreamWriter encodes the output.

The using statement wraps around the action you perform in the sense that the IDisposable.Dispose is called on the stream object once the actions are complete, and the resources, like file handle and memory related to this action, are released. This helps the app cleanup after the task is done and doesn't use resources longer than they are actually needed. Your StreamWriter has an important and useful additional argument apart from the file, which can be true or false. When it's true, the file will not be overwritten, but the new content will be appended.

Type aliasing helps you resolve ambiguity when you are dealing with multiple types. It also means you can avoid importing a whole namespace to perform your operations. This works the same way as aliasing namespaces, but it adds the alias for the scope of file in which it appears. It does not allow you to create global aliases that work across projects. You also have the option of aliasing generic types, but for this to work, you need to pass the parameter type.

Here is an example alias for a specific type:

1
2
using SW = System.IO.StreamWriter
using FS = System.IO.FileStream
csharp

Here is an example of a generic alias for a type:

1
2
using NINT = System.Nullable<System.Int32>;
using UDBL = System.Nullable<System.Double>;
csharp

Conclusion

In this guide, you learned about aliasing. You saw how aliasing namespaces and types allows you to build more robust, yet clean applications. First, we clarified the using keyword and aliasing as a concept, then turned our sights towards more technical examples. You saw four examples demonstrating the core use cases for aliasing and how it might benefit your applications.

I hope this has been informative for you and I hope you have found what you were looking for. If you liked this guide, give it a thumbs up and stay tuned for more.

0