在C#中将字符串转换为类型[重复]

Posted

技术标签:

【中文标题】在C#中将字符串转换为类型[重复]【英文标题】:Convert String to Type in C# [duplicate] 【发布时间】:2012-06-21 21:07:21 【问题描述】:

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

我试过了

Type.GetType("System.Int32")

例如,它似乎可以工作。

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

我事先不知道字符串中的内容,所以这是我将其转换为真实类型的唯一来源。

Type.GetType("NameSpace.MyClasse");

有什么想法吗?

【问题讨论】:

向我们展示您的示例失败代码,同时向我们展示原始类型。 另外,请告诉我们您为什么/要做什么。可能有一种解决方法不需要您发送该类型的字符串表示形式。 【参考方案1】:

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

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

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

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

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

【讨论】:

它工作正常......我现在唯一的问题是当我有一个 System.Collections.List 或 IList 时。我怎样才能做到这一点 ?因为我不仅想要列表类型,还想要列表包含的类型。例如 List 。请记住,我事先不知道字符串中的内容,我只需要输入一个真正的类型。有可能吗? @Vinhent:在这一点上它很棘手——你需要从类型参数中解析出通用部分,并使用Type.MakeGenericType。您可以控制输入的格式吗?像List<string> 这样的名字是个棘手的名字,因为string 是一个特定于C# 的别名。 我看到您的另一篇帖子这样做:Type type = Type.GetType("System.Collections.Generic.List`1[System.String]");这将是我需要的东西。因为我收到了字符串,我必须在 Type 中解析它。是的,我对字符串的格式有一些控制,但我不知道它是否会是一个列表、字符串、整数、自己的解决方案对象。它很好用,但不适用于 List。 @Vinhent:只是在试验,看起来您需要将方括号加倍以获得完全限定的名称:Type.GetType("System.Collections.Generic.List1[[namespace.myClass, AssemblyName]]")` IList<T> 也是。 @Vinhent:要调试所有这些情况,请选择一些东西并打印出它的全名,例如typeof(string[]).FullName。如果您自己学习如何做这将比向我询问每个变体要容易得多。【参考方案2】:

试试:

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");

【讨论】:

关键是 Type.GetType 正在为 OP 返回 null。请参阅我的答案以了解最可能的原因。 它工作正常......我现在唯一的问题是当我有一个 System.Collections.List 或 IList 时。我怎样才能做到这一点 ?因为我不仅想要列表类型,还想要列表包含的类型。例如 List 。请记住,我事先不知道字符串中的内容,我只需要输入一个真正的类型。有可能吗? 可能要注意,'inputString' 需要是完整的命名空间,因为这就是我在比较你的和他的时所做的。【参考方案3】:

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

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

请注意,您拥有的有关您尝试加载的类型的信息越多,就可以显着提高其性能。

【讨论】:

它工作正常......我现在唯一的问题是当我有一个 System.Collections.List 或 IList 时。我怎样才能做到这一点 ?因为我不仅想要列表类型,还想要列表包含的类型。例如 List 。请记住,我事先不知道字符串中的内容,我只需要输入一个真正的类型。有可能吗?【参考方案4】:

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

【讨论】:

以上是关于在C#中将字符串转换为类型[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在c#中将字符串转换为日期[重复]

在C#中将Char数组转换为字符串[重复]

如何在 C# 中将字符串转换为日期时间 [重复]

c#中将单引号字符串转换为uint [重复]

如何在C#中将字节转换为字符串[重复]

在 C# 中将 APRIL,03/2013 字符串转换为 DateTime [重复]