C# "using" keyword
In today's tutorial, we are going to discuss one of the keywords we frequently need to use: the using keyword!
Let's get straight to it!
The using keyword can be used in two contexts:
- As namespace directive
- In using statement blocks
1. Namespace directive
There are three ways in which we can use using here:
- Make use of namespaces (traditional usage)
- Make aliases for namespaces
- Use static methods from classes namespaces
Down below I will explain each one of them, with a simple example involving writing a message to the console.
1.1. Make use of namespaces (traditional usage)
As we know, to write a message to the console we must use our friend Console.WriteLine. We have two ways of calling Console.WriteLine. The first one is by calling the fully qualified name, which in this case would be System.Console.WriteLine. The second one would be using the using keyword. The problem with the first approach is that, whenever we want to Console.WriteLine, we must prepend with System. Doing this once is fine, but imagine having to do so multiple times. Even further, imagine if we had a bigger namespace, say Amazing.Big.Complex.DomainNamespace, which would be needed to call every time we wanted to call a method. This would degrade very much the readability of our code.
In the following figure, you can see an example of this using statement, as well as the other "not so good" use case mentioned.
1.2. Make aliases for namespaces
Creating aliases for namespaces, at a visual glance, seems like creating a variable. In order to better explain this concept, please refer to the below image.
As you can see in the first line, we create kinda a variable to store an alias for a specific namespace. In this case, it would not be worth it to make it, but with a bigger codebase, it could make sense in order to organize and make things look easier to read. Beware that this is not a widely used practice!
After declaring the alias we use it in the method WriteMessageToConsoleWithAlias.
1.3. Use static methods from classes namespaces
In this example, the WriteLine method is a static method from a static class (Console class). Every time we want to execute the WriteLine method, we must call Console first. We can improve that by using the static class in the namespace. The following figure shows how to do so.
As you can see from the first line, we have inserted the static keyword and also added the Console class to the namespace. This will allow us to use the static methods inside the Console class in our code without always needing to write Console.WriteLine. You can see this inside the WriteMessageToConsoleWithStaticMethod, where we call the WriteLine method without needing to prepend the Console class.
2. using statement blocks
The using block statements are used when we want to create and manage object resources in a specific scope. When the scope ends, those resources are freed. Using the using block is important because there are types of objects that the Garbage Collector cannot clear, so we need to release such objects explicitly. Examples of such objects are file streams or database connections. Please refer to this article for more information on this topic.
If that might seem confusing, let's have a look at this simple, but clarifying, coding example, which writes a specific content to a file.
public void WriteToFile(string fileName, string content){
using (StreamWriter writer = new StreamWriter(filename))
{
writer.WriteLine(content);
} //after this, resources used are freed
}
The important aspect to notice here is that the objects we use in the parenthesis of the using statement must implement the IDisposible interface. This interface contains the Dispose method that will be called whenever the scope of the using block ends. This Dispose method objective should be cleaning the object mentioned before.
If we don't do what we mentioned before, and simply wrote two WriteLine methods from two StreamWriter, we would get an error (similar to the one you see in the figure down below). That error occurs because the resources (from which file1.txt is one of them) that are used are not freed up like they are when we use them inside the using block.
But if, instead, you use the using blocks, you don't have this error, due to the freeing of the resources. The following image shows just that.
😁 I hope this has helped!
That's everything for now! Thank you so much for reading.
The source code for this tutorial can be found here.
If you have any questions please feel free to drop them off. Follow me if you want to read more about these kinds of topics!