En principio, si desde código
perteneciente a una clase definida en un cierto espacio de nombres se desea
hacer referencia a tipos definidos en otros espacios de nombres, se ha de
referir a los mismos usando su nombre completamente calificado. Por ejemplo:
namespace
EspacioEjemplo.EspacioEjemplo2
{
class
ClaseEjemplo
{}
}
class Principal // Pertenece al espacio de nombres global
{
public static void Main ()
{
EspacioEjemplo.EspacioEjemplo2.ClaseEjemplo
c = new EspacioEjemplo.EspacioEjemplo2.ClaseEjemplo();
}
}
Como puede resultar muy pesado
tener que escribir nombres tan largos en cada referencia a tipos así definidos,
en C# se ha incluido un mecanismo de importación de espacios de nombres que usa
la siguiente sintaxis:
using <espacioNombres>;
Este tipo de sentencias siempre
ha de aparecer dentro de una definición de espacio de nombres antes que
cualquier definición de miembros de la misma y permiten indicar cuáles serán
los espacios de nombres que se usarán implícitamente dentro de ese espacio de
nombres. A los miembros de los espacios de nombres así importados se les podrá
hacer referencia sin tener que usar calificación completa, como muestra la
siguiente versión del último ejemplo:
using EspacioEjemplo.EspacioEjemplo2;
namespace
EspacioEjemplo.EspacioEjemplo2
{
class
ClaseEjemplo
{}
}
// (1)
class Principal // Pertenece al espacio de nombres global
{
public static void ()
{
//
EspacioEjemplo.EspacioEjemplo2. está implícito
ClaseEjemplo
c = new ClaseEjemplo();
}
}
Nótese que la sentencia using
no podría haberse incluido en la zona marcada en el código como (1) el código porque entonces se violaría la regla de
que todo using
ha aparecer en un espacio de nombres antes que cualquier definición de miembro,
ya que la definición del espacio de nombres EspacioEjemplo.EspacioEjemplo2
es un miembro del espacio de nombres global.
Sin embargo, el siguiente código si que sería válido:
namespace
EspacioEjemplo.EspacioEjemplo2
{
class
ClaseEjemplo
{}
}
namespace Principal
{
using
EspacioEjemplo.EspacioEjemplo2;
class
Principal // Pertenece al espacio de
nombres global
{
public static void Main()
{
ClaseEjemplo
c = new ClaseEjemplo();
}
}
}
En este caso el using
aparece antes que cualquier otra definición de tipos dentro del espacio de
nombres en que se incluye (Principal)
Sin embargo, ahora la importación hecha con el using sólo será válida
dentro de código incluido en ese mismo espacio de nombres, mientras que en el
caso anterior era válida en todo el fichero al estar incluida en el espacio de
nombres global.
Si una sentencia using
importa miembros de igual nombre que miembros definidos en el espacio de
nombres donde se incluye, el using no se produce error alguno pero se da
preferencia a los miembros no importados.
Un ejemplo:
namespace N1.N2
{
class A {}
class B {}
}
namespace N3
{
using N1.N2;
class A {}
class C: A {}
}
En este ejemplo C deriva de N3.A en
vez de N1.N2.A. Si queremos que
ocurra lo contrario tendremos que referenciar a N1.N2.A
por su nombre completo al definir C
o, como se explica a continuación, usar un alias.