miércoles, 2 de octubre de 2013

Namespaces en C# - Parte 2

Tabla de Contenido

0. Introducción
1. Aliasing de Namespaces y Tipos
2. Características Avanzadas de Namespaces
2.1 Extern
2.2 Calificadores alias de Namespace
3. Conclusiones
4. Glosario
5. Referencias

0. Introducción

En la primera parte de namespaces en C# se presentaron los conceptos generales y principales de estas construcciones en el lenguaje; su utilidad para la estructuración de los artefactos software integrales de un proyecto. En esta segunda parte me voy a extender en asuntos de como renombramiento (en inglés, aliasing), características avanzadas, y cualificadores (qualifiers, en inglés).

1. Aliasing de Namespaces y Tipos

Vamos a suponer la situación en donde se han agregado referencias de dos assemblies de distintos desarrolladores, sin embargo, éstos contienen tipos de datos que nos interesan pero que conflictan por su nombre de tipo.

Fijémonos en estos namespaces sencillos:

Archivo C# DevSmart.cs [enlace alternativo]:
Archivo C# AndesSoft.cs [enlace alternativo]:
Ambos namespaces contienen -DevSmart y AndesSoft- contienen un tipo con el mismo nombre (a pesar de que su implimentación sea diferente): ValidadorEmail. Si un desarrollador quisiera hacer uso de ambos tipos en su programa, éste va a experiementar conflictos de tipos:

Conflicto de nombres de tipos
Figura 1. ProgramaCliente.cs.
Obsérvese con cuidado que el nombre de tipo ValidadorEmail genera el conflicto que se describe en la sección resaltada con amarillo en la Figura 1.

El problema anterior queda resuelto gracias al uso de aliasing de tipos. Esto consiste en asignar un alias a por lo menos uno de los tipos de los namespaces. Esta es la sintaxis [2]:

using   identificador  =   namespace-o-nombre-de-tipo   ;

Ahora, pasemos a solucionar el problema que se nos presentó en el ejemplo de arriba; así:

Archivo C# ProgramaCliente.cs [enlace alternativo]: 
El aliasing también funciona para los namespaces. Su uso es así de sencillo:

Archivo C# AliasingNamespaces.cs [enlace alternativo]:

En la línea 1 -using R = System.Reflection;- se crea un alias que (R) que referencia al namespace System.Reflection. Luego en la línea 7 -R.PropertyInfo p;- se utiliza el alias mencionado, y se crea una variable (p) de tipo PropertyInfo.

2. Características Avanzadas de Namespaces

2.1 Extern

Cuando utilicemos librerías de un mismo desarrollador pero en diferentes versiones, lo más seguro es que aparezcan conflictos por los espacios de nombres. Entonces se hace necesario un mecanismo que permita importar las librearías sin que se generen tales conflictos y el programa pueda usar diferentes implementaciones de los tipos disponibles en cada versión de la librería.

A través del siguiente ejemplo quedará más claro el concepto anterior:

Esta clase la compilamos usando el compilador de línea de comandos de C#:



Archivo C# UtilidadesV2.cs [enlace alternativo]:
Compilamos la clase:



Pasamos a crear la clase de prueba (o clase cliente):

Archivo C# PruebaLibrerias.cs [enlace alternativo]:
El paso a seguir: compilar la clase PruebaLibrerias.cs. Así:




Este comando generará un error de compilación debido a la ambigüedad del namespace Utilidades:

Error de compilación de librerías
Figura 2. Error de compilación (CS0433 [2]).
Para solucionar esta ambigüedad de la aplicación hacemos uso del alias con extern [3]:

Primero debemos modificar la clase PruebaAplicacion.cs. De esta manera:

Archivo C# PruebaLibrerias.cs [enlace alternativo]:
Se compila de esta manera:


2.2 Calificadores alias de namespace

En la situación donde los nombres de tipos conflicta con los nombres de espacio debido a la preferencia del compilador por los artefactos más cercanos en alcance. Véase el siguiente ejemplo:

Archivo C# ConflictoNamespaceYClase.cs [enlace alternativo]:

En la línea 12 se crea una confusión: ¿se está instanciando un objeto de la clase B del namespace A, o, un objeto de la clase B anidada de la clase A? El compilador, como se dijo arriba, da prioridad al último caso.

Este conflicto se resuelve usando el namespace raíz (global) [4].  El símbolo sintáctico (token) :: sirve para calificar el nombre de un namespace desde la raíz. Código de solución:

3. Conclusiones

Nos hemos volcado en un tema interesante con los namespaces, en particular cómo resolver problemas de ambigüedad con librerías que tienen los mismos nombres de namespaces y que son utilizadas en un mismo programa y que sus nombres entran en conflicto.

4. Glosario

  • Ambigüedad
  • extern
  • root
  • token

5. Referencias

[1]: C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.
[2]: Compiler Error CS0433 - http://msdn.microsoft.com/en-us/library/64wh5743.aspx
[3]: extern (C# Reference) - http://msdn.microsoft.com/en-us/library/e59b22c5.aspx
[4]: global (C# Reference) - http://msdn.microsoft.com/en-us/library/cc713620.aspx
O

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.