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: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:
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
Post a Comment