找回密码
 立即注册

QQ登录

只需一步,快速开始

Carl

版主

49

主题

213

帖子

962

积分

版主

Rank: 7Rank: 7Rank: 7

积分
962

活字格认证微信认证勋章

QQ
Carl
版主   /  发表于:2009-12-10 10:02  /   查看:7351  /  回复:0
Post by "ted", 2006-12-26, 18:01
-----------------------------------------------------

Introduction
Namespace in .Net is an additional information, if provided will enable unique naming of types within an assembly. This articles assumes C# knowledge and all the issues/resolutions provided are applicable to C# 1.1/2.0

For e.g., you can have a class called Console in your assembly, within a namespace named, say, MyNamespace. System namespace also have a class named Console. We can use both of the classes in the program
Problems with Namespaces in 1.1
If you worked on a large project in .Net in the past, you must have faced some problems with Namespaces. Namespaces, were introduced in .Net to eliminate the naming collisions between different code developed at different locations. But as large and large projects were developed, there were some shortcomings were observed. Some of them included:

a. Same typename can be used in multiple namespaces. In this scenario, types in local namespaces can mask types in global namespaces. And this leads to an ambiguous situation
b. Same typenames can be used in multiple assemblies. When these assemblies were used in the same application, again, there will be ambiguity in referencing the types
c. using aliases can lead to ambiguous identification. Aliases can mask the type if not taken care.
Namespaces in 2.0
To address all the issues that arose in the previous version, 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.

lets look at the following piece of code:
namespace Aeroplane
{

interface IGoodsCarrier

{

}



interface IPassengerCarrier

{

}



namespace Boeing

{

class Boeing737 : IPassengerCarrier { ... }

}



namespace AirBus

{

class AirBusA340 : IPassengerCarrier { ... }

}
}


using Manufacturer = Aeroplace.AirBus;


namespace Aeroplane
{

namespane Company { ... }



class Program

{

static void Main()

{

IPassengerCarrier carrier = new Manufacturer.AirBusA340();

}

}
}


This works well with both 1.1 and 2.0, but if somebody adds
namespace AeroPlane
{

namespace Manufacturer { ... }
}
1.1 will throw a compile time exception as there is a colliding namespace with the alias qualifier.
2.0 addresses this issue with a minor syntax change. We'll now use :: operator to resolve the ambiguity.
//replace
//IPassengerCarrier carrier = new Manufacturer.AirBusA340();
//with
IPassengerCarrier carrier = new Manufacturer::AirBusA340();
this will unambiguously refer to Aeroplane.AirBus.

:: 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, lets 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 orginization, you might have observed that developers working on two different assemblies define the same typename in the same namespace. 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();

}

}
}
Summary
Though these things seem to be very uncommon situations, In large projects, these are quite common and sometimes very frustating. Now, we have these changes to C# 2.0 which will help working with large projects not frustating.
From : http://www.codeproject.com/useritems/Namespaces_20.asp



Reply by "J2.NETe", 2006-12-27, 9:30
-----------------------------------------------------

LZ的第三种方法中的External Aliasing是要在编译的时候在写reference的时候加上Alias的。
有没有其它的方式,可以在IDE中使用这样的功能呢?
比如有无类似如下的写法?
extern alias First = first.dll;
extern alias Second = second.dll;



Reply by "SmiletotheLife", 2006-12-27, 9:55
-----------------------------------------------------

重名的Namespace在.Net1.1有下面的问题:
a. 一些类型名(typename)在多个名称空间(Namespace)中使用。为了实现这种需求,我们把类型定义在全局的名称空间中,而这样做,可能因为重名(相同的typename),而引起二义性。
b.在不同的DLL(assembly)文件中分别定义了重名的类型。当另外一个程序同时引用这些DLL,这些重名的类型将会引起歧异。
c. 使用别名也可能因为和类型名相同而导致歧异。
.Net2.0使用下面的方法解决上述问题:
a. 名城空间别名
b.全局操作符(globe:
c. 外部别名(Extern Aliasing)
----------------------------
To Ted:
Namespace Aliasing的Demo code中:
using Manufacturer = Aeroplace.AirBus
是不是应该改为:
using Manufacturer = Aeroplane.AirBus
全篇都是在使用Aeroplane的名称空间,而没有Aeroplace。

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部