Skip to main content

C# Snippet - The Many Uses Of The Using Keyword [Beginner]


What is the first thing that pops into your mind when you think of the using keyword for C#? Probably those lines that always appear at the top of C# code files - the lines that import types from other namespaces into your code. But while that is the most common use of the using keyword, it is not the only one. Today we are going to take a look at the different uses of the using keyword and what they are useful for.

The Using Directive

There are two main categories of use for the using keyword - as a "Using Directive" and as a "Using Statement". The lines at the top of a C# file are directives, but that is not the only place they can go. They can also go inside of a namespace block, but they have to be before any other elements declared in the namespace (i.e., you can't add a using statement after a class declaration).

Namespace Importing

This is by far the most common use of the keyword - it is rare that you see a C# file that does not have any of this type of use:
using System;
using System.Linq;
using System.Windows;
 
This type of use allows you to use the types in the given namespace without having to use the full declaration. So instead of doing something like this:
namespace MyNamespace
{
  public class MyWindow : System.Windows.Window
  {
    public System.String SomeString { get; set; }
    public System.Collections.Generic.List<int> SomeList { get; set; }
  }
}
 
You get to do this:
using System;
using System.Collections.Generic;
using System.Windows;

namespace MyNamespace
{
  public class MyWindow : Window
  {
    public String SomeString { get; set; }
    public List<int> SomeList { get; set; }
  }
}
 
Visual Studio has some handy built in help for managing using directives as well - if you type a class name that you don't currently have a using statement for, you can hit the key chord Alt+Shift+F10 and get the following menu:
Alt+Shift+F10
menu

 

Class Aliasing

You can also use the using keyword to give an alias for a namespace. For example, say you need to use the System.Drawing.Graphics class and you also need to use the System.Windows.Point class. You can't do the following, because you will get a compile error:
using System.Windows;
using System.Drawing;

namespace MyNamespace
{
  public class MyWindow : Window
  {
    public Point SomePoint { get; set; }
    public Graphics SomeGraphics { get; set; }
  }
}

//Error: 'Point' is an ambiguous reference between 'System.Windows.Point' 
//and 'System.Drawing.Point'
 
But you can use class aliasing and do the following:
using System.Windows;
using GdiGraphics = System.Drawing.Graphics;

namespace MyNamespace
{
  public class MyWindow : Window
  {
    public Point SomePoint { get; set; }
    public GdiGraphics SomeGraphics { get; set; }
  }
}
 
This means that the name GdiGraphics refers to System.Drawing.Graphics in this file - and you don't have to pull in the entire System.Drawing namespace (getting rid of the conflict).

Another handy use of class aliasing is reducing the length of long type names:
using System.Collections.Generic;

namespace MyNamespace
{
  public class MyClass
  {
    public KeyValuePair<List<string>, List<int>> MyFunction(
      KeyValuePair<List<string>, List<int>> input)
    {
      return input;
    }
  }
}
 
That is a really long type name! And the more you have to type it, the more annoying it will get. So you can alias it:
using System.Collections.Generic;

namespace MyNamespace
{
  using WeirdType = KeyValuePair<List<string>, List<int>>;

  public class MyClass
  {
    public WeirdType MyFunction(WeirdType input)
    { return input; }
  }
}

 

Namespace Aliasing

Very similar to class aliasing, you can alias namespaces. Take that first example from class aliasing - say you needed a couple different types from System.Drawing instead of just the one. It could get annoying making a bunch of class aliases, so you could just make a namespace alias and use it like so:
using System.Windows;
using GDI = System.Drawing;

namespace MyNamespace
{
  public class MyWindow : Window
  {
    public Point SomePoint { get; set; }
    public GDI.Graphics SomeGraphics { get; set; }
    public GDI.Image SomeImage { get; set; }
  }
}

 

Other Handy Info

Visual Studio has some handy options in the context menu for dealing with using directives:
Context Menu Using
Options

These allow you to clean up the using directives in a file - which can be quite useful, because using directives tend to accumulate, and they don't disappear automatically when they are no longer used.

 

The Using Statement

The other main use of the using keyword is as a using statement. The using statement has a completely different use than the using directive - it used for easy disposing of IDisposable objects. The pattern without the using statement looks like this:
public void MyFunction()
{
  var brush = new SolidBrush(Color.Aqua);

  //Do Stuff

  brush.Dispose();
}
 
However, there is a problem with this code - what if an exception gets thrown inside of "Do Stuff"? Then the brush will never get disposed. You can rectify this by doing:
public void MyFunction()
{
  SolidBrush brush = null;
  try
  {
    brush = new SolidBrush(Color.Aqua);

    //Do Stuff
  }
  finally
  {
    if (brush != null)
    { brush.Dispose(); }
  }
}
 
However, that pattern can get annoying really quick. So instead, you can use the using statement:
public void MyFunction()
{
  using(var brush = new SolidBrush(Color.Aqua))
  {
    //Do Stuff
  }
}
 
The variable brush gets disposed when it goes out of scope, and behind the scenes this is implemented with a try-finally (so even in the case of exceptions, the object will get disposed).

You can even declare multiple objects in a single using statement (just like how you would outside of a using statement, with a comma):
public void MyFunction()
{
  using(Brush brush1 = new SolidBrush(Color.Aqua),
    brush2 = new SolidBrush(Color.Aqua))
  {
    //Do Stuff
  }
}
 
Both brush1 and brush2 will get disposed when they leave scope.

That about covers the uses of the using keyword. I personally especially like class aliasing - it has helped me to cut down on code clutter a number of times.

Comments

Popular posts from this blog

C# Snippet - Shuffling a Dictionary [Beginner]

Randomizing something can be a daunting task, especially with all the algorithms out there. However, sometimes you just need to shuffle things up, in a simple, yet effective manner. Today we are going to take a quick look at an easy and simple way to randomize a dictionary, which is most likely something that you may be using in a complex application. The tricky thing about ordering dictionaries is that...well they are not ordered to begin with. Typically they are a chaotic collection of key/value pairs. There is no first element or last element, just elements. This is why it is a little tricky to randomize them. Before we get started, we need to build a quick dictionary. For this tutorial, we will be doing an extremely simple string/int dictionary, but rest assured the steps we take can be used for any kind of dictionary you can come up with, no matter what object types you use. Dictionary < String , int > origin = new Dictionary < string , int >();

C# WPF Printing Part 2 - Pagination [Intermediate]

About two weeks ago, we had a tutorial here at SOTC on the basics of printing in WPF . It covered the standard stuff, like popping the print dialog, and what you needed to do to print visuals (both created in XAML and on the fly). But really, that's barely scratching the surface - any decent printing system in pretty much any application needs to be able to do a lot more than that. So today, we are going to take one more baby step forward into the world of printing - we are going to take a look at pagination. The main class that we will need to do pagination is the DocumentPaginator . I mentioned this class very briefly in the previous tutorial, but only in the context of the printing methods on PrintDialog , PrintVisual (which we focused on last time) and PrintDocument (which we will be focusing on today). This PrintDocument function takes a DocumentPaginator to print - and this is why we need to create one. Unfortunately, making a DocumentPaginator is not as easy as