How to get a Type from a C# type name string?

后端 未结 2 732
谎友^
谎友^ 2021-01-25 05:27

I\'ve been looking at return values for Type.Namespace, Type.Name, Type.FullName, and Type.AssemblyQualifiedName. There are

2条回答
  •  醉梦人生
    2021-01-25 06:06

    So, basically per our conversation in the comments the goal here is to get a type object (for whatever purpose) from a name of the type. Calling "Type.GetType()" works for simple types but for generics and other types it doesn't work because the name needs to be qualified. The key, then is to use the code compiler to actually have the C# code engine find and get the type. The following is a working program that does just that:

    using System;
    using System.Reflection;
    using Microsoft.CSharp;
    using System.CodeDom.Compiler;
    
    namespace SimpleCompileTest
    {
        class Program
        {
            public static void Main(string[] args)
            {
                string typeName = "System.Collections.Generic.List";
                Type theType = GetTypeFromName(typeName);
            }
    
            private static Type GetTypeFromName(string typeName)
            {
                // double open and close are for escape purposes
                const string typeProgram = @"using System; using System.Collections.Generic; using System.IO;
                    namespace SimpleTest
                    {{
                        public class Program
                        {{
                            public static Type GetItemType()
                            {{
                                {0} typeTest = new {0}();
                                if (typeTest == null) return null;
                                return typeTest.GetType();
                            }}
                        }}
                    }}";
    
                var formattedCode = String.Format(typeProgram, typeName);
    
                var CompilerParams = new CompilerParameters
                    {
                        GenerateInMemory = true,
                        TreatWarningsAsErrors = false,
                        GenerateExecutable = false,
                        CompilerOptions = "/optimize"
                    };
    
                string[] references = { "System.dll" };
                CompilerParams.ReferencedAssemblies.AddRange(references);
    
                var provider = new CSharpCodeProvider();
                CompilerResults compile = provider.CompileAssemblyFromSource(CompilerParams, formattedCode);
                if (compile.Errors.HasErrors) return null;
    
    
                Module module = compile.CompiledAssembly.GetModules()[0];
                Type mt = null; MethodInfo methInfo = null;
    
                if (module != null) mt = module.GetType("SimpleTest.Program");
                if (mt != null) methInfo = mt.GetMethod("GetItemType");
                if (methInfo != null) return (Type)methInfo.Invoke(null, null);
    
                return null;
            }
        }
    }
    

    One really important thing to note - you need to add the list of assemblies to the compiler that you hope to pull types from. That means if you have a custom type that you want to reference you need to provide that to the compiler, but otherwise, this works! Enjoy!

提交回复
热议问题