开发者

typeof or Type.GetType for a non qualified type name

开发者 https://www.devze.com 2022-12-14 08:28 出处:网络
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 typ

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?


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.


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?


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消