简体   繁体   中英

typeof or Type.GetType for a non qualified type name

I want to do do something like this :

Type t=typeof(int?);

or

Type t=typeof(MemoryStream);

However the parameter is string ("int?","MemoryStream",etc) and it is not in assembly qualified type name so Type.GetType(string) won't work.

The reason I need to get type is because I'm doing simple code generator application and it need to handle value & reference type different way, and also if type is Enumerable it will iterate and do specific operation.

Do you have any clue about this?

The reason typeof is able to cope with this is that the compiler knows about the built-in C# syntactic shortcuts ( int for System.Int32 , X? for Nullable<X> etc) and look through the using directives, and it knows which assemblies to look through.

If you want to be able to deal with anything the C# compiler can deal with, you'll need that information yourself. (I assume you won't need namespace aliases etc though...)

Can you provide it a list of assemblies and a list of namespaces to check?

Well, you could create a compiler-on-the-fly, like so:

string getTypeHack = @"using System; public static class TypeHacker {{ public static Type GetThisType() {{ return typeof({0}); }} }}";

CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateInMemory = true;
parameters.GenerateExecutable = false;
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, string.Format(getTypeHack, "int"));

Type hacker = results.CompiledAssembly.GetType("TypeHacker");
MethodInfo hack = hacker.GetMethod("GetThisType");
Type actualType = (Type)hack.Invoke(null, null);

... but this is probably a really bad idea. You need a new in-memory assembly for each type you are testing. Some problems off the top of my head:

  • You're going to have memory-leakage-city with the code above; you would need to mitigate that.
  • It's going to be slow.
  • It's ugly.
  • You still may have assembly resolution issues, depending on which types you are allowing.

(I might actually downvote myself for suggesting this...) :^)

Is there any way to refactor the application to pass a Type? It's going to make your life so much easier.

You could enumerate through all types using AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetExportedTypes())

For each type you could compare its name to your name.

This works well if you don't use it too much as the perfromance is not very good. You could improove it by creating a Dictionary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM