Crear un objeto a partir de una cadena con Activator.CreateInstance

 

Pues eso… como el título indica, te voy a explicar cómo crear (instanciar sería más correcto) un objeto a partir del "nombre" de una clase, pero estando ese nombre dentro de una cadena. Y como de costumbre, con el código de ejemplo tanto para (mi querido) Visual Basic como para (mi obligado) C# 😉

Lo de "obligado" también lo puedes tomar por "obrigado" que en portugués significa "gracias", de agradecimiento, no te vayas a pensar que el C# me hace gracia… bueno, algunas veces me hago a la idea que me está guiñando… (por lo del punto y coma) 😉

 

Vamos al tema.

Si tienes una cadena con el nombre de una clase, puedes crear una nueva instancia de esa clase utilizando la clase Activator, más concretamente el método compartido CreateInstance.

Para que funcione la conversión de cadena a objeto del tipo correcto debes tener en cuenta que:

  1. Indiques el espacio de nombres del tipo en la cadena
  2. La clase puede ser una clase derivada (o implementada)
  3. El tipo tenga un constructor público y sin parámetros
  4. Las clases abstractas (abstract / MustInherit) no sirven ya que no se pueden instanciar
  5. Que la clase a crear esté accesible, vamos que si tú no puedes crear el objeto ni indicando el tipo de forma explícita el Activator no creo que haga milagros…

 

Una vez que sabemos las condiciones que debemos seguir para instanciar clases a partir del contenido de un string vamos a ponerlo a prueba con unos ejemplos en los que comprobaremos lo dicho en la lista anterior y algo más.

El código para hacer la conversión lo podemos simplificar al máximo, pero en ese caso sólo deberíamos usarlo para crear clases que cumplan las 2 primeras condiciones indicadas en la lista anterior.
Para casos indicados en los puntos 3 y 4 habría que usar un bloque try/catch para detectar la excepción que ocurrirá, ya que el tipo es correcto pero no se puede instanciar.
Para los casos que cumplan la última condición (el tipo no existe o no está accesible) podemos usar una comprobación que en realidad es para saber si el tipo es del mismo tipo a convertir o se deriva de él, esa comprobación la haremos por medio del método IsAssignableFrom (definido en la clase Type).

Veamos primero el código que hace la conversión sin más comprobaciones 
(el código completo lo he puesto en un método para que sea más fácil hacer varias de las pruebas).

VB:

Dim laClase = "ActivatorVB.Colega"

Dim elTipo As Type = Type.GetType(laClase)

Dim obj As Colega = TryCast(Activator.CreateInstance(elTipo), Colega)

If obj IsNot Nothing Then
    obj.Nombre = "Pepe"
    obj.Email = "pepe@outlook.com"
End If

 

C#:

var laClase = "ActivatorCS.Colega";

Type elTipo = Type.GetType(laClase);

Colega obj = Activator.CreateInstance(elTipo) as Colega;

if (obj != null)
{
    obj.Nombre = "Pepe";
    obj.Email = "pepe@outlook.com";
}

 

Un par de aclaraciones (tanto para VB como para C#, las aclaraciones) sobre este código:

En VB utilizo TryCast y en C# utilizo as para hacer la conversión ya que de esa forma, si el objeto no se puede crear se devuelve un valor nulo.

Si en VB utilizara CType o DirectCast o en C# hiciera la conversión con (Colega) y la conversión falla, produciría un error.

Aunque en realidad esto sólo nos salvará de los casos indicados en el punto 5 de las "condiciones" para realizar la instanciación de la clase a partir de una cadena. Pero bueno, ya sabes que hay varias formas de hacer conversiones entre tipos 😉

 

Para hacer la comprobación de si el tipo es adecuado por medio del método IsAssignableFrom lo haríamos de la siguiente forma:

 

'  VB
' Esto controlará las clases que no se basan en Colega
If Not GetType(Colega).IsAssignableFrom(elTipo) Then Console.WriteLine("El tipo: {0} no es del tipo adecuado." & vbLf & "", laClase) Return End If // C# // Esto controlará las clases que no se basan en Colega if (!typeof(Colega).IsAssignableFrom(elTipo)) { Console.WriteLine("El tipo: {0} no es del tipo adecuado.\n", laClase); return; }

 

Ya solo me queda ponerte todo el código de prueba en el que he hecho las pruebas esas que conforman la lista para estar seguro de que es así…

Te recomiendo que hagas tú las tuyas propias, incluso usando las partes comentadas en dicho código.

En el método Main2 de dicho código he puesto un ejemplo de una clase que implementa una interfaz.

 

Nota:

El código completo lo pongo aparte para que no llene tanto esto.

Además te pongo separado el de Visual Basic de el de C# y tu eliges el que quieras.

También está publicado en Pastebin.

 

Espero que te sea de utilidad.

Nos vemos.

Guillermo

P.S.

Los enlaces:

El de VB en Pastebin

El de C# en Pastebin

El de VB en mi blog

El de C# en mi blog

elGuille_luna300x200

Esta entrada fue publicada en cosas técnicas, mis cosas y etiquetada , , , , , . Guarda el enlace permanente.

Una respuesta a Crear un objeto a partir de una cadena con Activator.CreateInstance

  1. Crear un objeto a partir de una cadena con Activator.CreateInstance » elGuille mola, es algo genial. Me encanta vuestra web.

Los comentarios están cerrados.