Method that returns a class

6

I'm trying to create a method that takes a string and returns an instance of the class with the last name, eg "Calculator", will return me an instance of class "Calculator" time to determine which type it returns, because from what I researched I need to pass the type pro method as well. I tried: Type Tipo = Type.GetType("NomeDaClasse"); and then passing var x = RetornaClasse<Tipo>("Calculadora"); but to no avail. (Actually, I can not even decide the method to try.

static T RetornaClasse<T>(string nome) where T : class
{
    return (T)Assembly.GetExecutingAssembly().CreateInstance(nome);
}

Usage: The return of this method will be parameter for this Generic Class:

public class Generico<T> where T : class
{
    public T Objeto { get; set; }

    public string ListarAtributos()
    {
        var p = Objeto.GetType().GetProperties();
        string atributos = String.Empty;

        foreach (PropertyInfo pop in p) // Lista de atributos
            atributos += (String.Concat("[", pop.Name, "] = [", pop.GetValue(Objeto, null), "]\n"));

        return atributos;
    }

    public string[] ListarMetodos()
    {
        var m = Objeto.GetType().GetMethods();
        string[] metodos = new string[m.Length];

        for (int i = 0; i < m.Length; i++)
            metodos[i] = String.Concat(i, " [+] ", m[i].Name, "\n");
        return metodos;
    }

    // TODO: Setar atributos, usar métodos
}

Solution:

static object RetornaClasse(string nome)
{
    var classe = Assembly.GetExecutingAssembly().GetTypes().First(x => x.Name == nome);
    var instancia = Activator.CreateInstance(classe);
    return instancia;
}
    
asked by Laerte 07.05.2014 в 20:50
source

1 answer

8

If the type is in the same Assembly that is running, you can do this:

var t = Assembly.GetExecutingAssembly().GetTypes().First(x => x.Name == "Calculadora");

And then use the type to create a new instance:

var objectOfType = Activator.CreateInstance(t);

Example of a fully functional program, using generic argument, and LINQ for a little easier:

public class Program
{
    public static void Main(string[] args)
    {
        var computador = GetInstanciaDoTipo<Computador>("Calculadora");

        var usarReflexao = new UsandoReflexaoParaAcessarObjeto();
        usarReflexao.Objeto = computador;
        var resultado1 = usarReflexao.TentarSomar();
        var resultado2 = usarReflexao.SomarUsandoDynamic();
        var resultado3 = computador.Somar(1, 2);
    }

    private static T GetInstanciaDoTipo<T>(string nomeTipo)
    {
        return
            (T)Assembly.GetExecutingAssembly()
                .GetTypes()
                .Where(t => t.Name == nomeTipo)
                .Where(t => typeof(T).IsAssignableFrom(t))
                .Select(Activator.CreateInstance)
                .First();
    }

    abstract class Computador
    {
        public abstract int Somar(int a, int b);
    }

    class Calculadora : Computador
    {
        public override int Somar(int a, int b)
        {
            return a + b;
        }
    }

    /// <summary>
    /// Esta classe usa reflexão para acessar o objeto, seja lá qual o tipo dele.
    /// Também há um método usando dynamic, para exemplificar como é mais fácil usar dynamic do que reflection,
    /// quando queremos executar algo dinamicamente.
    /// </summary>
    public class UsandoReflexaoParaAcessarObjeto
    {
        public object Objeto { get; set; }

        public int? TentarSomar()
        {
            if (this.Objeto != null)
            {
                var type = this.Objeto.GetType();
                var methodInfo = type.GetMethod("Somar");
                var result = methodInfo.Invoke(this.Objeto, new object[] { 1, 2 });
                return (int)result;
            }

            return null;
        }

        public int? SomarUsandoDynamic()
        {
            if (this.Objeto != null)
            {
                dynamic dyn = this.Objeto;
                return dyn.Somar(1, 2);
            }

            return null;
        }
    }
}
    
answered by 07.05.2014 / 21:01
source