web-dev-qa-db-fra.com

Convertir une chaîne en caractères C #

Si je reçois une chaîne contenant le nom d'une classe 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?

157
Vinhent

Vous pouvez uniquement utiliser seulement le nom du type (avec son espace de nom, bien sûr) si le type est dans mscorlib ou l'assembly appelant. . Sinon, vous devez également inclure le nom de l'Assemblée:

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

Si le nom de l'Assemblée est fortement défini, vous devez également inclure toutes ces informations. Consultez la documentation de Type.GetType(string) pour plus d'informations.

Si vous avez déjà une référence à Assembly (par exemple, via un type connu), vous pouvez également utiliser Assembly.GetType :

_Assembly asm = typeof(SomeKnownType).Assembly;
Type type = asm.GetType(namespaceQualifiedTypeName);
_
353
Jon Skeet

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 :)

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

YourType your = (YourType)Activator.CreateInstance("AssemblyName", "NameSpace.MyClass");
30
abatishchev

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 ses performances.

13
Chris Kerekes

utilisez la méthode LoadType suivante pour utiliser System.Reflection pour charger tous les assemblys enregistrés ( GAC ) et référencés et 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();
}
3
Ehsan Mohammadi