Welcome to this installment of the .NET Nuts & Bolts column. The focus of this article will be on highlighting the C# using keyword. The using keyword has been in the language since the initial release. Something many developers do not realize is that the using keyword is a dual-purpose keyword. You’ll touch on the common usage that C# developers should be familiar with, add a twist to it, and focus on the lesser known use that is valuable to understand.
Using Directive
Many readers will recognize the C# using keyword for its most common usage, which is to import types defined in namespaces into the scope of a code file. It is a directive when employed in this fashion. It adorns the top of a code file to import a namespace so that it can be used throughout the code file in more of a shorthand notation. Example code without the using directive:
namespace CodeGuru.Example { class Program { static void Main(string[] args) { Program.TestCfg(); } public static string TestCfg() { return System.Configuration .ConfigurationSettings.AppSettings["MySetting"]; } } )
Here is the example from above refactored to demonstrate the using directive to import types:
using System.Configuration; namespace CodeGuru.Example { class Program { static void Main(string[] args) { Program.TestCfg(); } public static string TestCfg() { return ConfigurationSettings.AppSettings["MySetting"]; } } }
In addition to importing a namespace, the using directive can be used to create what is known as an alias. Aliasing allows you to assign an alternate name to use in place of a particular namespace. It looks syntactically similar to a variable declaration and assignment except it just denotes an alternate name to replace the namespace, not unlike the act of defining a synonym. The following example demonstrates a refactoring of the examples above to employ an alias for the System.Configuration.ConfigurationSettings namespace:
using cfg = System.Configuration.ConfigurationSettings; namespace CodeGuru.Example { class Program { static void Main(string[] args) { Program.TestCfg(); } public static string TestCfg() { // use of the cfg alias return cfg.AppSettings["MySetting"]; } } }
I personally will typically employ the using directive to import types and not bother with aliasing, but I know others who enjoy aliasing.
Using Statement
The dual purpose of the using keyword of which many C# developers are painfully unaware is employing using as a statement. When used as a statement, it defines a scope at the end of which a specific object will be disposed once the scope is exited. This may not seem earth shattering, but the first time that your application runs out of available database connections because a developer unknowingly wasn’t closing and disposing a DataReader object it will become pretty clear pretty fast. The following sample code demonstrates a code mistake that I see all too often around use of DataReaders:
using System.Data; using System.Data.SqlClient; using cfg = System.Configuration.ConfigurationSettings; namespace CodeGuru.Example { class Program { static void Main(string[] args) { Program.TestCfg(); } public static void TestCfg() { string connectString = cfg.AppSettings["ConnectionString"]; string query = "Select * from Northwind"; SqlConnection connection = new SqlConnection(connectString); SqlCommand command = new SqlCommand(query, connection); IDataReader reader = null; try { reader = command.ExecuteReader(); while (reader.Read()) { // Some processing stuff here } // Works great as long as we are on a happy path // with no errors reader.Close(); } catch (SqlException e) { // Some error handling stuff here } } } }