代码之家  ›  专栏  ›  技术社区  ›  Anton Setiawan

非限定类型名的typeof或type.gettype

c#
  •  0
  • Anton Setiawan  · 技术社区  · 16 年前

    我想这样做:

    Type t=typeof(int?);
    

    Type t=typeof(MemoryStream);
    

    但是参数是字符串(“int”)。“,”memoryStream“等),但它不在程序集限定的类型名中,因此type.getType(string)将不起作用。

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

    你对此有什么线索吗?

    3 回复  |  直到 16 年前
        1
  •  1
  •   Dave Mateer    16 年前

    好吧,你 能够 动态创建编译器,如下所示:

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

    ……但这可能是个很坏的主意。对于正在测试的每种类型,都需要一个新的内存中程序集。我脑子里有些问题:

    • 使用上面的代码,您将拥有内存泄漏城市;您需要减轻这一点。
    • 会很慢的。
    • 太难看了。
    • 根据所允许的类型,您仍然可能存在程序集解析问题。

    (我可能会对自己的建议投反对票…):^)

    是否有任何方法可以重构应用程序以传递类型?这会让你的生活轻松很多。

        2
  •  1
  •   Jon Skeet    16 年前

    原因 typeof 能够处理这一点的是,编译器知道内置的C语法快捷方式( int 对于 System.Int32 , X? 对于 Nullable<X> 等) 查看使用指令, 它知道要查看哪些程序集。

    如果您希望能够处理C编译器可以处理的任何事情,那么您自己就需要这些信息。(我假设您不需要名称空间别名等…)

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

        3
  •  0
  •   Matthias    16 年前

    您可以使用 appdomain.currentDomain.getAssemblies().selectMany(a=>a.getExportedTypes())

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

    如果你不用太多,这个效果很好,因为表演不太好。你可以通过创建一本字典来改进它。