将字符串转换为C#中的类型

时间:2012-06-19 18:55:48

标签: c# .net string types

如果我收到一个包含类名的字符串,并且我想将此字符串转换为实际类型(字符串中的那个),我该怎么办?

我试过

Type.GetType("System.Int32")
例如,它似乎有效。

但是当我尝试使用自己的对象时,它总是返回null ...

我不知道提前在字符串中会有什么,所以这是我将其转换为实际类型的唯一来源。

Type.GetType("NameSpace.MyClasse");

有什么想法吗?

4 个答案:

答案 0 :(得分:336)

如果类型位于mscorlib或调用程序集中,则只能使用 类型的名称(当然还有其名称空间)。否则,您还必须包含程序集名称:

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

如果程序集名称很强,那么您必须包含所有这些信息。有关详细信息,请参阅Type.GetType(string)的文档。

或者,如果您已经引用了程序集(例如,通过众所周知的类型),则可以使用Assembly.GetType

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

答案 1 :(得分:30)

尝试:

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

Jon Skeet通常是正确的:)

更新:您可以按照Jon提到的方式,以各种方式指定包含目标类型的程序集,或者:

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

答案 2 :(得分:13)

如果您确实想要按名称获取类型,可以使用以下内容:

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

请注意,您可以大大提高这方面的性能,了解有关您尝试加载的类型的更多信息。

答案 3 :(得分:3)

使用以下LoadType方法使用System.Reflection加载所有已注册(GAC)和引用的程序集并检查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();
}