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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11107536/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 16:30:39  来源:igfitidea点击:

Convert String to Type in C#

c#.netstringtypes

提问by vinhent

If I receive a string that contains the name of a class and I want to convert this string to a real type (the one in the string), how can I do this?

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

I tried

我试过

Type.GetType("System.Int32")

for example, it appears to work.

例如,它似乎有效。

But when I try with my own object, it always returns null ...

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

I have no idea what will be in the string in advance so it's my only source for converting it to its real type.

我事先不知道字符串中会有什么,所以它是我将其转换为真实类型的唯一来源。

Type.GetType("NameSpace.MyClasse");

Any idea?

任何的想法?

采纳答案by Jon Skeet

You can only use justthe name of the type (with its namespace, of course) if the type is in mscorlibor the calling assembly. Otherwise, you've got to include the assembly name as well:

您只能使用刚刚类型的名称(连同其命名空间,当然),如果该类型是mscorlib或调用程序集。否则,您还必须包含程序集名称:

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

If the assembly is strongly named, you've got to include all that information too. See the documentation for Type.GetType(string)for more information.

如果程序集是强命名的,则还必须包含所有这些信息。有关Type.GetType(string)更多信息,请参阅文档。

Alternatively, if you have a reference to the assembly already (e.g. through a well-known type) you can use Assembly.GetType:

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

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

回答by abatishchev

Try:

尝试:

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

Jon Skeet is right as usually :)

Jon Skeet 和往常一样是对的 :)

Update:You can specify assembly containing target type in various ways, as Jon mentioned, or:

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

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

回答by Chris Kerekes

If you really want to get the type by name you may use the following:

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

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

Note that you can improve the performance of this drastically the more information you have about the type you're trying to load.

请注意,您可以通过获得有关您尝试加载的类型的更多信息来显着提高其性能。

回答by Ehsan Mohammadi

use following LoadType method to use System.Reflectionto load all registered(GAC) and referenced assemblies and check for typeName

使用以下 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();
}