To address all the issues that arise in the previous version of .Net,, C# 2.0 introduced some new features like: | ||
1. Namespace aliasing 2. global :: operator 3. Extern Aliasing |
||
Namespace Aliasing | ||
With Namespace aliasing parallel namespaces are much more convenient and namespace aliasing also offers greater flexibility. | ||
Let’s look at the following piece of code: | ||
namespace Bus { interface IGoodsCarrier { } interface IPassengerCarrier { } namespace ACBus { class Mahindra : IPassengerCarrier { ... } } namespace NonACBus { class Ashoka : IPassengerCarrier { ... } } } using Manufacturer = Bus.NonACBus; namespace Bus { namespane Company { ... } class Program { static void Main() { IPassengerCarrier carrier = new Manufacturer.NonACBus(); } } } |
||
This works well with both 1.1 and 2.0, but if somebody adds | ||
namespace Bus { namespace Manufacturer { ... } } |
||
.Net version 1.1 will throw a compile time exception as there is a colliding namespace with the alias qualifier.
.Net version 2.0 addresses this issue with a minor syntax change. We’ll now use :: operator to resolve this ambiguity. |
||
//replace //IPassengerCarrier carrier = new Manufacturer.NonACBus (); //with IPassengerCarrier carrier = new Manufacturer::NonACBus(); |
||
This will unambiguously refer to ACBus, NonACBus.
:: Operator identifies the left hand side operator of the instruction as an alias and not a namespace. |
||
global:: Operator | ||
To understand the importance of this operator, let’s look at this sample code | ||
namespace MyOrg { namespace System { public class Console { ... } public class Program { static void Main() { // problem. ambiguous call to Console as it is //available in System namespace and MyOrg.System //namespace Console.WriteLine("Hello"); // this is also ambiguous System.Console.WriteLine("Hello"); // these code lines will not refer to the top level //System.Console } } } } |
||
global:: operator will unambiguously refer to the top level scope in these situations lets check the modified code | ||
namespace MyOrg { namespace System { public class Console { ... } public class Program { static void Main() { // unambiguous call. Calls Console class available at //MyOrg.System namespace Console.WriteLine("Hello"); // this is also unambiguous global::System.Console.WriteLine("Hello"); } } } } |
||
External Aliasing | ||
If you are working in a large organization, you might have observed that developers working on two different assemblies define the same typename in the same namespace. E.g. Most of the times in Utility classes | ||
lets look at this code to understand this situation | ||
//in assembly - first.dll namespace MyOrg.Utility { public class Helper { public static bool SendMail() { //sends mail through the SmtpServer } } } //in assembly - second.dll namespace MyOrg.Utility { public class Helper { public static bool SendMail() { //sends mail from the mail account of the user } } } //consumer code - references to both first.dll and second.dll namespace MyOrg.Utility { public class Program { public static void NotifyUser() { //this will fail at compile time as the assembly namespaces //are colliding Helper.SendMail(); } } } |
||
External aliasing can resolve ambiguous references to the namespaces. External aliasing provides assembly qualified namespace aliases. extern is the keyword that should be used to provide the assembly qualified namespaces. | ||
Defining the extern alias involves two things. Firstly, we need to define the extern alias in the source code of the consumer and we also need to map the aliases to the assemblies through the compiler options. | ||
Let us look at how the above program changes | ||
//consumer code - references to both first.dll and second.dll //while compiling the following references should be user //C:\Code>csc /r:First=first.dll /r:Second=second.dll Program.cs //this can be done from VS 2005, by opening the properties of the //referenced dll's properties //and providing aliases in the Aliases property extern alias First; //should match the alias provided in the //compiler options extern alias Second; //should match the alias provided in teh //compiler options using FirstUtility = First::MyOrg.Utility; using SecondUtility = Second::MyOrg.Utility; namespace MyOrg.Utility { public class Program { public static void NotifyUser() { //this will not fail FirstUtility.Helper.SendMail(); SecondUtility.Helper.SendMail(); } } } |
||
|