martes, 3 de junio de 2014

Receta No. 3-11 en C#: Comprobación del Tipo de un Objeto

Tabla de Contenido

0. Introducción
1. Problema
2. Solución
3. Discusión de la Solución
3.1 Comprobación con GetType
3.2 Operador is
3.3 Operador as
3.4 Type en dominios de aplicación
4. Práctica: Código Fuente C#
5. Conclusiones
6. Glosario
7. Literatura & Enlaces

0. Introducción

El tema principal de esta receta consistirá en probar el tipo de un objeto. Para lograrlo, demostraré el uso de tres formas distintas. Con esto, vamos a afianzar y a extender nuestro conocimiento acerca del uso de tipos en tiempo de compilación y en tiempo de ejecución. También introduciré (en breve) varias construcciones del lenguaje para llevar a cabo esta operación de comprobación.

1. Problema

Además del proceso de obtención de información de un tipo (Receta No. 3-11 en C#: Comprobación del Tipo de un Objeto), ahora necesitamos comprobar (probar) el tipo de un objeto.

2. Solución

Para cubrir el requerimiento de la sección anterior contamos con tres medios para alcanzarlo:
  • GeType de Object para la obtención de una referencia Type con la representación del objeto original.
  • Operador is.
  • Operador as.

3. Discusión de la Solución

Vamos a explorar las tres formas anteriores (sección 2) en las siguientes sub-secciones.

3.1 Comprobación con GetType

Con el método GetType [2] de Object podemos comprobar el tipo de un objeto. Firma:

public Type GetType()

Este método retorna una instancia de Type. Esta instancia representa el objeto original.

En código fuente lo podemos utilizar de la siguiente manera:

Archivo de código fuente UsoComprobacionGetType.cs [enlace alternativo]:
Con el método static ReferenceEquals [4] (Object) comparamos las referencias de Type obtenidas con el método GetType sobre las variablese  num1, y num2.

> Prueba de ejecución.

Resultado:

¿`num1` y `num2` son del mismo tipo?: True
¿`num1` y `num3` son del mismo tipo?: False

3.2 Operador is

Con el operador is [3] podemos comprobar si un objeto (instancia) es compatible con un tipo (clase, interfaz, enumeración, delegado, &c.).

Archivo de código fuente Usois.cs [enlace alternativo]:
El operador is permite comparar un objeto con un tipo. En las líneas 29, 33 se lleva a cabo esa comparación:

if ( o is A)

-y-

if (o is B)

Tenemos que tener en cuenta que la comparación se realiza siguiendo la ascendencia de los tipos en una jerarquía de herencia.

> Prueba de ejecución.

Resultado:

El objeto `o` es de clase `A`.
El objeto `o` es de clase `B`.
El objeto `o` es de clase `B`.
El objeto `o` no corresponde con ninguna de las clases.

[Nota: La determinación de los tipos a comparar se realiza en tiempo de compilación.]

3.3 Operador as

Con el operador as [5] podemos realizar conversiones entre tipos compatibles, e inclusive con valores null de variables de tipo por referencia.

Uso:

expresion as Tipo

Como muestran en [5], la expresión anterior es igual a:

expresion is Tipo ? (Tipo) expresion : (Tipo) null;

Ahora veamos un ejemplo de uso y utilidad:

Archivo de código fuente Usoas.cs [enlace alternativo]:

En la línea 13 creamos un arreglo de Object. En las siguientes líneas (16-21) agregamos tipos de referencia.

En las líneas 23-38 recorremos el arreglo arregloObject, y, específicamente en la línea 26 utilizamos el operador as para tratar de convertir cada uno de los elementos en el arreglo arregloObject a string:

string cadena = arregloObject[i] as string;

> Prueba de ejecución.

Resultado:

0: El elemento en 0 no es un objeto de string.
1: El elemento en 1 no es un objeto de string.
2: 'Blog xCSw'
3: El elemento en 3 no es un objeto de string.
4: El elemento en 4 no es un objeto de string.
5: El elemento en 5 no es un objeto de string.

Notas finales:
  • A diferencia del proceso de conversión estándar, a través del operador as no se genera la excepción System.InvalidCastException [6] cuando no se puede completar la conversión por divergencia en los tipos.
  • Cuando la operación de conversión no es compatible, la evaluación generada por el operador as, genera el valor null.
  • La resolución en la conversión se lleva en tiempo de ejecución.

3.4 Type en dominios de aplicación

En [1] advierten que la CLR se encarga de representar cada tipo definido en un modelo de tipos en Type. Esto permite que las comparaciones de objetos con tipos sea eficiente. Además, en la Figura 1 agrega un comentario acerca del funcionamiento de este método entre distintos assemblies.
Funcionamiento de Type dominios de aplicación
Figura 1. Funcionamiento de Type dominios de aplicación [1].

4. Práctica: Código Fuente C#

Conjuguemos el conocimiento adquirido en la sección anterior (3) en este ejemplo de código fuente C#.

Archivo de código fuente ComprobacionTipoObjeto.cs [enlace alternativo]:
Compilación:


  1. csc /target:exe ComprobacionTipoObjeto.cs

> Prueba de ejecución.

Resultado:
Resultado prueba de operadores as, is, typeof y el método GetType
Figura 2. Resultado prueba de operadores as, is, typeof y el método GetType.

5. Conclusiones

Aprendimos a comprobar el tipo a través de tres de los operadores as, is, typeof. Estos operadores permiten determinar la naturaleza de una instancia de una clase de objeto. Tenemos que considerar que estos operadores son más apropiados dependiendo el contexto: tiempo de compilación o tiempo de ejecución; por ejemplo con as podemos verificar que omite el lanzamiento de excepciones en conversiones de tipo.

6. Glosario

  • AppDomain
  • Casting
  • CLR
  • Conversión
  • Dominio de aplicación
  • Object

7. Literatura & Enlaces

[1]: Visual C# 2010 Recipes by Allen Jones and Adam Freeman. Copyright 2010 Allen Jones and Adam Freeman, 978-1-4302-2525-6.
[2]: Object.GetType Method (System) - http://msdn.microsoft.com/en-us/library/vstudio/system.object.gettype(v=vs.100).aspx
[3]: is (C# Reference) - http://msdn.microsoft.com/en-us/library/scekt9xw.aspx
[4]: Object.ReferenceEquals Method (System) - http://msdn.microsoft.com/en-us/library/system.object.referenceequals(v=vs.110).aspx
[5]: as (C# Reference) - http://msdn.microsoft.com/en-us/library/cscsdfbt.aspx
[6]: InvalidCastException Class (System) - http://msdn.microsoft.com/en-us/library/system.invalidcastexception(v=vs.110).aspx


J

No hay comentarios:

Publicar un comentario

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