If two assemblies use exactly the same name for a type it should be obvious that it is going to impossible to use both types unless the compiler can uniquely identify each one. External aliases are used to resolve type name abiguities and :: is the separator for a namespace alias and the namespace member.
As a crazy example create an assembly named OtherSystem containing a type called System.String.
namespace System {
public class String {
}
}
Any attempt to use this type will almost certainly result in compilation failure and a message such as
The type 'System.String' exists in both 'OtherSystem.dll' and 'mscorlib.dll'
To fix this problem the OtherSystem assembly must be given an external alias when it is referenced by another project.
The external alias is defined on the C# compiler command line
csc /reference:MySystem=OtherSystem.dll ExternalAliasTest.cs
but may also be set within Visual Studio on the reference property sheet for OtherSystem.dll.
Source code wishing to refer to the alias must have a matching external alias directive to ensure that any type names prefixed with MySystem:: are resolved properly.
extern alias MySystem;
using System;
namespace ExternalAliasTest {
class Program {
static void Main() {
Console.WriteLine(typeof(System.String).AssemblyQualifiedName);
Console.WriteLine(typeof(MySystem::System.String).AssemblyQualifiedName);
Console.ReadLine();
}
}
}
The output of the program shows that we are able to access both System.String types.
System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.String, OtherSystem, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Alan.