This article is currently in the process of being translated into Spanish (~99% done).
Instantiating a class
Hasta el momento, hemos trabajado con los tipos de .NET que ya han sido instanciados. Pero con Reflexión, podemos de hecho crear instancias en tiempo de ejecución también, sabiendo el nombre de la clase que queremos instanciar. Hay una gran cantidad de formas de hacerlo, pero yo prefiero obtener una referencia al constructor que deseo utilizar, invocarlo, y luego utilizar el valor retornado como mi instancia. Acá hay un ejemplo de cómo hacer exactamente eso. Escribe el código primero, luego lo explicaré todo:
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace ReflectionTest
{
class Program
{
static void Main(string[] args)
{
Type testType = typeof(TestClass);
ConstructorInfo ctor = testType.GetConstructor(System.Type.EmptyTypes);
if(ctor != null)
{
object instance = ctor.Invoke(null);
MethodInfo methodInfo = testType.GetMethod("TestMethod");
Console.WriteLine(methodInfo.Invoke(instance, new object[] { 10 }));
}
Console.ReadKey();
}
}
public class TestClass
{
private int testValue = 42;
public int TestMethod(int numberToAdd)
{
return this.testValue + numberToAdd;
}
}
}
He definido una simple clase para testear esto, llamada TestClass. Esta simplemente contiene un campo privado y un método público. El método retorna el valor de la propiedad privada, con el valor del parámetro añadido a esta. Ahora, lo que queremos es crear una nueva instancia de esta TestClass, llamar el TestMethod y mostrar la salida en la consola.
En este ejemplo, tenemos el lujo de la posibilidad de poder usar el typeof() directamente en el TestClass, pero en algún punto, tu tal vez solo puedas hacerlo mediante el uso del nombre de la clase deseada. En este caso, tú puedes obtener una referencia a este mediante el ensamblado donde está declarado, como fue demostrado en el capítulo acerca de los Type.
Así que, con una referencia Type a la clase, le solicitamos el constructor por defecto, mediante el uso del método GetConstructor(), pasándole System.Type.EmptyTypes como parámetro. En caso de que quisiéramos un constructor específico, tendríamos que proveer una colección de Type, cada uno definiendo que parámetro del constructor que estamos buscando sería necesario.
Una vez que tengamos una referencia al constructor, simplemente llamamos el método Invoke() para crear una nueva instancia de la clase TestClass. Pasamos null como el parámetro al Invoke(), ya que no queremos especificar ningún parámetro. Usamos el GetMethod(), junto con el nombre del método que queremos, para obtener la función TestMethod(), y luego una vez más usamos la magia del método Invoke() para llamar esta función. Esta vez tenemos que especificar un parámetro, en la forma de una colección de objetos. Hacemos esto fácilmente, especificando el numero 10 como el único parámetro que necesitamos, y luego hacemos la salida del resultado de la invocación del método. ¡Todo esto gracias a la magia de la Reflexión!