C# typeof或Type.GetType用于非限定类型名称

C# typeof或Type.GetType用于非限定类型名称,c#,C#,我想这样做: Type t=typeof(int?); 或 但是,参数是string(“int?”,“MemoryStream”等),并且它不在程序集限定的类型名称中,因此type.GetType(string)不起作用 我需要获取类型的原因是因为我正在执行简单的代码生成器应用程序,它需要以不同的方式处理值和引用类型,而且如果类型是可枚举的,它将迭代并执行特定的操作 你对此有什么线索吗?之所以typeof能够处理这个问题,是因为编译器知道内置的C#语法快捷方式(int用于System.Int3

我想这样做:

Type t=typeof(int?);

但是,参数是string(“int?”,“MemoryStream”等),并且它不在程序集限定的类型名称中,因此type.GetType(string)不起作用

我需要获取类型的原因是因为我正在执行简单的代码生成器应用程序,它需要以不同的方式处理值和引用类型,而且如果类型是可枚举的,它将迭代并执行特定的操作


你对此有什么线索吗?

之所以
typeof
能够处理这个问题,是因为编译器知道内置的C#语法快捷方式(
int
用于
System.Int32
X
用于
Nullable
等)并查看使用指令,它知道要查看哪些程序集

如果你想处理C#编译器能处理的任何事情,你自己就需要这些信息。(我假设您不需要名称空间别名等…)


您可以为它提供一个程序集列表和要检查的名称空间列表吗?

您可以使用 AppDomain.CurrentDomain.GetAssemblys().SelectMany(a=>a.GetExportedTypes())

对于每种类型,您可以将其名称与您的名称进行比较

如果你不经常使用它,这会很好,因为它的性能不是很好。您可以通过创建字典来改进它。

您可以动态创建编译器,如下所示:

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);
。。。但这可能是一个非常糟糕的主意。对于正在测试的每种类型,都需要一个新的内存中程序集。我脑海中浮现出一些问题:

  • 使用上面的代码,您将有内存泄漏;你需要缓解这种情况
  • 会很慢的
  • 很难看
  • 根据所允许的类型,您可能仍然存在程序集解析问题
(实际上,我可能会对自己的建议投反对票……:^)


有没有办法重构应用程序以传递类型?这将使您的生活变得更加轻松。

我做了一些类似于迭代AppDomain.CurrentDomain.getAssemblys()和do Assembly.GetType的事情,但它仍然不能工作。int的名称是什么?将为null'1,因此它与int?不同。所以我不能依赖名称属性你是对的-泛型类型是个问题。它只适用于非泛型类型。哇,谢谢!它起作用了!如果我使用你的解决方案,我想我会缓存结果。OK,注意你的记忆。缓存你能缓存的东西,尽快处理任何一次性的东西,并为“int”、“string”等低挂果实创建查找表。如果你想办法进行重构,或者包括Jon提到的程序集,那会更好。
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);