Using Directives and Namespace in C#
UsingDirectivesMustBePlacedWithinNamespace is one of the rules of StyleCop and I was trying to figure out why StyleCop recommends having using directives defined within the namespace.
Most of the books and articles (including mine) we have read do not really have using blocks within the namespace. So is it really a good practice? If yes, why? Let’s check that in this article.
To illustrate the difference, I would choose a very simple example with 2 classes – Program (default one when a console application is created) and Environment (with the name same as System.Environment.)
- using System;
- namespace MyNS.Application
- {
- internal class Program
- {
- private static void Main(string[] args)
- {
- Console.WriteLine(Environment.GetName());
- Console.WriteLine(Math.Round(2.2, 0));
- }
- }
- }
- namespace MyNS
- {
- public class Environment
- {
- public static string GetName()
- {
- return "MyEnvironment";
- }
- }
- }
In the above example, when I refer to Environment on Line 8, I am referring to my own class MyNS.Environment and not to System.Environment. This is because the namespace System is defined outside the namespaces (NS and NS.Application). In other words,
When the using directive is defined outside the namespace, the compiler will first search for the class (here, Environment) within the namespaces. If it does not find the class locally (as for Math class on Line 9), it will try to search for the class in the references
So what happens if I move the using block inside the namespace (MyNS.Application)? Will it break the above code? Yes, because it will give precedence to System.Environment over MyNS.Environment and it will not find the method GetName in System.Environment
- namespace MyNS.Application
- {
- using System;
- internal class Program
- {
- private static void Main(string[] args)
- {
- Console.WriteLine(Environment.GetName());
- Console.WriteLine(Math.Round(2.2, 0));
- }
- }
- }
So is the principle of StyleCop is correct, then it would break our code if we have used class names that are also part of the System namespaces (or in the referenced assemblies). And it would require fixing by creating aliases like
- namespace MyNS.Application
- {
- using System;
- // Create an alias here
- using Environment = MyNS.Environment;
- internal class Program
- {
- private static void Main(string[] args)
- {
- Console.WriteLine(Environment.GetName());
- Console.WriteLine(Math.Round(2.2, 0));
- }
- }
- }
This ensures that your code is StyleCop compliant and also refers to your own classes instead of System defined classes or those in the referenced assemblies