Lo dicho el código completo para Visual Basic del ejemplo comentado en:
Crear un objeto a partir de una cadena con Activator.CreateInstance
(el enlace al de Visual Basic está en ese mismo artículo)
//----------------------------------------------------------------------------- // Crear un objeto a partir de una cadena con Activator (05/Ene/13) // // // ©Guillermo 'guille' Som, 2013 //----------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Text; namespace ActivatorCS { public sealed class CrearClase { public static void Main() { // La clase a crear var elNombre = "ActivatorCS.Colega"; crearColega(elNombre); // Esta clase se llama igual, // pero no es del mismo tipo // y no pasaría la prueba de IsAssignableFrom, // aunque no daría error al hacer la conversión // pero no crearía una instancia, // por tanto Activator devolvería nulo, // en realidad el valor nulo lo devuelve // la operación de conversión de tipos // por eso en C# utilizo "as Colega" en lugar de "(Colega)" // para hacer la conversión elNombre = "OtroEspacio.Colega"; crearColega(elNombre); // esta clase se basa en la que queremos crear // aunque esté en otro espacio de nombres elNombre = "OtroEspacio.Coleguilla"; crearColega(elNombre); // este tipo no existe, // pero debemos usar IsAssignableFrom // para no provocar una excepción elNombre = "Activator.Colega"; crearColega(elNombre); // esta se basa en la nuestra // pero es abstracta (no tiene constructor) // ya dará un error al crearla // aunque pasaría la prueba de IsAssignableFrom try { elNombre = "ActivatorCS.ColegaAbstracto"; crearColega(elNombre); } catch (Exception ex) { Console.WriteLine("Mrw! (o Ups!) esta clase {0} da error: {1}", elNombre, ex.Message); } Console.ReadKey(); } private static void crearColega(string laClase) { Type elTipo = Type.GetType(laClase); // el equivalente en c# de TryCast es hacer el cast con "as tipo" // aunque también se puede comprobar si se puede crear el objeto // Esto contralará 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; } Colega obj = Activator.CreateInstance(elTipo) as Colega; if (obj != null) { obj.Nombre = "Pepe"; obj.Email = "pepe@outlook.com"; Console.WriteLine("Objeto creado correctamente: {0}{1}{2}, {3}", obj.GetType().Name, "\r\n", obj.Nombre, obj.Email); } else { Console.WriteLine("Parece que el tipo: {0} no es del tipo adecuado.", laClase); } Console.WriteLine(); } void pruebaDirecta() { 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"; } } static void Main2() { var laClase = "ActivatorVB.unColega"; Type elTipo = Type.GetType(laClase); IColega obj = ((IColega)Activator.CreateInstance(elTipo)); if (obj != null) { obj.Nombre = "Pepe"; } } } public interface IColega { string Nombre { get; set; } } public class unColega : IColega { public string Nombre { get; set; } } public class Colega { public string Nombre { get; set; } public string Email { get; set; } } // Clase no instanciable public abstract class ColegaAbstracto : Colega { public int Edad { get; set; } } } namespace OtroEspacio { public class Colega { public string Nombre { get; set; } public int Edad { get; set; } } public class Coleguilla : ActivatorCS.Colega { public int Edad { get; set; } } // las clase selladas (sealed / NotInheritable) // se pueden usar, pero siempre deben tener // un constructor público sin parámetros public sealed class Coleguilla2 : ActivatorCS.Colega { //protected Coleguilla2() //{ //} //private Coleguilla2() //{ //} public int Edad { get; set; } } }
Nos vemos.
Guillermo
Hola Guillermo, saludos de Ecuador, sabes es interesante tu post, pero no se si te puedo molestar al ponerte un reto (mas que reto en realidad es una petición jeje).
En tu ejemplo de todas maneras necesitas tener la clase cuando haces algo como
Colega obj = Activator.CreateInstance(elTipo) as Colega;
Como podrias hacer lo mismo si digamos nunca sabes que vas a recibir colega, pero claro la clase existe en tu assembly.
Hola, no me lo he planteado nunca, puede que probara algo al principio de empezar con .net, pero de esto hace ya más de 10 años y ¡no me acuerdo! 😉
Pero supongo que se podrá hacer… lo más que probé fue a «compilar» código al vuelo…
De todas formas, me lo apunto a ver si encuentro la forma.
Esto lo he hecho porque estaba usando un código en el que no sé de antemano el nombre de la clase, pero como están derivadas de una misma clase base, simplemente he usado esa clase base para hacer el «cast».
pensando un poco… en realidad es de la misma forma, pero sin hacer la conversión y por tanto devolviendo un object; pero al no hacer el casting no podremos usar los métodos/miembros de la clase de forma «directa», además en C# tendrás que usar dynamic y en VB habrÃa que tener desactivada Option Strict.
De todas formas, lo comprobaré… no vaya a ser que… 😉
ya he puesto el código, en:
Si utilizas dynamic en C# acuérdate de agregar una referencia a Microsoft.CSharp
Lo que yo te decÃa, usando dynamic.
El problema es que si no «conoces» el tipo… ¿cómo lo vas a usar?
Disculpe como se crea una clase en C# en windows fomrs….? 😀
Ada, en mi sitio: http://www.elguille.info tienes un tutorial muy bueno para iniciarte en C#
namespace DAL.Impl.SQLServer
{
public abstract class SQLDALAdapter : DALSQLImplementation
{
protected override sealed IDataBaseSQLHelper GetDataBaseHelper()
{
return SqlServerHelper.GetInstace();
}
}
}
private SqlServerHelper() { }
public static SqlServerHelper GetInstace()
{
lock (syncRoot)
{
if (instance == null)
{
instance = new SqlServerHelper();
}
}
return instance;
}