210 votes

Convertir une chaîne en type c #

Si je reçois une chaîne contenant le nom d'une classe (objet) et que je souhaite convertir cette chaîne en un type réel (celui de la chaîne), comment puis-je procéder?

j'ai essayé

 Type.GetType("System.Int32")
 

par exemple, cela semble fonctionner.

Mais quand j'essaie avec mon propre objet, il retourne toujours null ...

Je n'ai aucune idée de ce qui sera dans la chaîne à l'avance, c'est donc ma seule source pour la convertir en son type réel.

 Type.GetType("NameSpace.MyClasse");
 

Une idée?

427voto

Jon Skeet Points 692016

Vous ne pouvez utiliser simplement le nom du type (avec son espace de noms, bien sûr) si le type est en mscorlib ou de la convocation de l'assemblée. Sinon, vous devez inclure le nom de l'assemblage ainsi:

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

Si l'assemblée est fortement nommé, vous devez inclure toutes les informations trop. Voir la documentation de l' Type.GetType(string) pour plus d'informations.

Sinon, si vous avez une référence à l'assembly (par exemple par l'intermédiaire d'un type bien connu), vous pouvez utiliser Assembly.GetType:

Assembly asm = typeof(SomeKnownType).Assembly;
Type type = asm.GetType(namespaceQualifiedTypeName);

38voto

abatishchev Points 42425

Essayer:

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

Jon Skeet a raison, comme d'habitude :)

Vous pouvez spécifier un assemblage contenant un type de cible de différentes manières, comme mentionné par Jon, ou:

 YourType your = (YourType)Activator.CreateInstance("AssemblyName", "NameSpace.MyClasse");
 

19voto

Chris Kerekes Points 544

Si vous voulez vraiment obtenir le type par nom, vous pouvez utiliser ce qui suit:

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

Notez que plus vous aurez d'informations sur le type que vous essayez de charger, plus vous pourrez améliorer considérablement ses performances.

4voto

Ehsan Mohammadi Points 71

utilisez la méthode LoadType suivante pour utiliser System.Reflection afin de charger tous les assemblys enregistrés ( GAC ) et référencés et de vérifier le typeName

 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();
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X