it-swarm.com.de

String in C # umwandeln

Wie kann ich vorgehen, wenn ich eine Zeichenfolge erhalte, die den Namen einer Klasse enthält, und diese Zeichenfolge in einen echten Typ (den in der Zeichenfolge) konvertieren möchte?

Ich habe es versucht

Type.GetType("System.Int32")

zum Beispiel scheint es zu funktionieren.

Aber wenn ich es mit meinem eigenen Objekt versuche, gibt es immer null zurück ...

Ich habe keine Ahnung, was in der Zeichenfolge im Voraus sein wird, daher ist es meine einzige Quelle für die Konvertierung in den realen Typ.

Type.GetType("NameSpace.MyClasse");

Irgendeine Idee?

157
Vinhent

Sie können nur den Namen des Typs (natürlich mit seinem Namensraum) verwenden, wenn sich der Typ in mscorlib oder im aufrufenden befindet Versammlung. Andernfalls müssen Sie auch den Assembly-Namen angeben:

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

Wenn die Assembly einen starken Namen hat, müssen Sie auch alle diese Informationen angeben. Weitere Informationen finden Sie in der Dokumentation zu Type.GetType(string) .

Wenn Sie bereits einen Verweis auf die Assembly haben (z. B. über einen bekannten Typ), können Sie auch Assembly.GetType verwenden:

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

Versuchen:

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

Jon Skeet hat wie immer recht :)

pdate: Sie können Assembly, die den Zieltyp enthält, auf verschiedene Arten angeben, wie Jon es erwähnt hat, oder:

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

Wenn Sie den Typ wirklich anhand des Namens erhalten möchten, können Sie Folgendes verwenden:

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

Beachten Sie, dass Sie die Leistung drastisch verbessern können, je mehr Informationen Sie über den Typ haben, den Sie laden möchten.

13
Chris Kerekes

verwenden Sie die folgende LoadType-Methode, um System.Reflection zu verwenden, um alle registrierten ( GAC ) und referenzierten Assemblys zu laden und nach typeName zu suchen

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