Convertir Cadena a Tipo en C # [duplicar]


Esta pregunta ya tiene una respuesta aquí:

Si recibo una cadena que contiene el nombre de una clase y quiero convertir esta cadena a un tipo real (el de la cadena), ¿cómo puedo hacer esto?

Lo intenté

Type.GetType("System.Int32")

Por ejemplo, parece que trabajo.

Pero cuando intento con mi propio objeto, siempre devuelve null ...

No tengo idea de lo que habrá en la cadena por adelantado, por lo que es mi única fuente para convertirla a su tipo real.

Type.GetType("NameSpace.MyClasse");

Alguna idea?

Author: Vinhent, 2012-06-19

4 answers

Solo puede usar solo el nombre del tipo (con su espacio de nombres, por supuesto) si el tipo está en mscorlib o en el ensamblado que llama. De lo contrario, también debe incluir el nombre del ensamblador:

Type type = Type.GetType("Namespace.MyClass, MyAssembly");

Si el ensamblado tiene un nombre fuerte, también debe incluir toda esa información. Ver la documentación para Type.GetType(string) para más información.

Alternativamente, si ya tiene una referencia al ensamblado (por ejemplo, a través de un tipo bien conocido) puede usar Assembly.GetType:

Assembly asm = typeof(SomeKnownType).Assembly;
Type type = asm.GetType(namespaceQualifiedTypeName);
 284
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-19 19:54:11

Intenta:

Type type = Type.GetType(inputString); //target type
object o = Activator.CreateInstance(type); // an instance of target type
YourType your = (YourType)o;

Jon Skeet tiene razón como siempre :)

Update: Puede especificar el ensamblado que contiene el tipo de destino de varias maneras, como mencionó Jon, o:

YourType your = (YourType)Activator.CreateInstance("AssemblyName", "NameSpace.MyClass");
 25
Author: abatishchev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-11 22:17:43

Si realmente desea obtener el tipo por nombre, puede usar lo siguiente:

System.AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes()).First(x => x.Name == "theassembly");

Tenga en cuenta que puede mejorar el rendimiento de esto drásticamente cuanta más información tenga sobre el tipo que está tratando de cargar.

 11
Author: Chris Kerekes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-19 19:07:40

Utilice el siguiente método LoadType para usar el sistema .Reflection para cargar todos los ensamblados registrados (GAC ) y referenciados y verificar el nombre del tipo

public Type[] LoadType(string typeName)
{
    return LoadType(typeName, true);
}

public Type[] LoadType(string typeName, bool referenced)
{
    return LoadType(typeName, referenced, true);
}

private Type[] LoadType(string typeName, bool referenced, bool gac)
{
    //check for problematic work
    if (string.IsNullOrEmpty(typeName) || !referenced && !gac)
        return new Type[] { };

    Assembly currentAssembly = Assembly.GetExecutingAssembly();

    List<string> assemblyFullnames = new List<string>();
    List<Type> types = new List<Type>();

    if (referenced)
    {            //Check refrenced assemblies
        foreach (AssemblyName assemblyName in currentAssembly.GetReferencedAssemblies())
        {
            //Load method resolve refrenced loaded assembly
            Assembly assembly = Assembly.Load(assemblyName.FullName);

            //Check if type is exists in assembly
            var type = assembly.GetType(typeName, false, true);

            if (type != null && !assemblyFullnames.Contains(assembly.FullName))
            {
                types.Add(type);
                assemblyFullnames.Add(assembly.FullName);
            }
        }
    }

    if (gac)
    {
        //GAC files
        string gacPath = Environment.GetFolderPath(System.Environment.SpecialFolder.Windows) + "\\assembly";
        var files = GetGlobalAssemblyCacheFiles(gacPath);
        foreach (string file in files)
        {
            try
            {
                //reflection only
                Assembly assembly = Assembly.ReflectionOnlyLoadFrom(file);

                //Check if type is exists in assembly
                var type = assembly.GetType(typeName, false, true);

                if (type != null && !assemblyFullnames.Contains(assembly.FullName))
                {
                    types.Add(type);
                    assemblyFullnames.Add(assembly.FullName);
                }
            }
            catch
            {
                //your custom handling
            }
        }
    }

    return types.ToArray();
}

public static string[] GetGlobalAssemblyCacheFiles(string path)
{
    List<string> files = new List<string>();

    DirectoryInfo di = new DirectoryInfo(path);

    foreach (FileInfo fi in di.GetFiles("*.dll"))
    {
        files.Add(fi.FullName);
    }

    foreach (DirectoryInfo diChild in di.GetDirectories())
    {
        var files2 = GetGlobalAssemblyCacheFiles(diChild.FullName);
        files.AddRange(files2);
    }

    return files.ToArray();
}
 3
Author: Ehsan Mohammadi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-04 21:43:33