Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 什么';在加载的程序集中按名称搜索类型的最快方法是什么?_C#_Performance_Reflection - Fatal编程技术网

C# 什么';在加载的程序集中按名称搜索类型的最快方法是什么?

C# 什么';在加载的程序集中按名称搜索类型的最快方法是什么?,c#,performance,reflection,C#,Performance,Reflection,我正在编写一种小型模板语言(很像Razor),在模板编译方面我必须做的一件事是基于(1)完全限定名或(2)非限定名+命名空间解析CLR枚举。例如: namespace Foo.Bar { public enum MyEnum { A, B } } // template: @using Foo.Bar; @using System; ... @Foo.Bar.MyEnum.A // fully qualified @MyEnum.A // unqualified, but in one

我正在编写一种小型模板语言(很像Razor),在模板编译方面我必须做的一件事是基于(1)完全限定名或(2)非限定名+命名空间解析CLR枚举。例如:

namespace Foo.Bar {
    public enum MyEnum { A, B }
}

// template:
@using Foo.Bar;
@using System;
...
@Foo.Bar.MyEnum.A // fully qualified
@MyEnum.A // unqualified, but in one of the specified namespaces
我当前的方法是扫描当前应用程序域中的所有程序集以查找枚举,如下所示:

string[] namespaces = // parsed from template
string typeName = // parsed from template
string fieldName = // parsed from template

var possibleResolutions = from type in AppDomain.CurrentDomain.GetAssemblies()
        .Where(a => !a.IsDynamic)
        .SelectMany(a => a.GetTypes())
    where type.IsEnum
    from @namespace in namespaces
    let fullName = @namespace + '.' + typeName
    // the replace is because nested enum types (like we have in AptOne, will have a fullname of namespace.OuterClass+InnerClass)
    where type.FullName.Replace('+', '.') == fullName
    let field = type.GetField(fieldName, BindingFlags.Public | BindingFlags.Static)
    where field != null;
我发现在冷启动时(主导所有其他模板编译时间),这可能会非常慢,几乎所有的时间都花在GetTypes()上。我想知道,有没有更快的方法来进行这种查找

请注意,我已经在缓存这些结果,因此我对这种解决方案不感兴趣。

您可以使用来扫描程序集而不进行反射,以生成枚举列表。从他们的网站:

CCI元数据API允许应用程序有效地分析或修改.NET程序集、模块和调试(PDB)文件。CCI元数据支持.NET System.Reflection和System.Reflection.Emit API的功能,但性能要好得多。它还提供了在两个.NET API中都不可用的附加功能


然后,如果需要实际类型,可以使用列表调用
Assembly.GetType()

经过一些实验,我发现
Assembly.GetType(string)
Assembly.GetTypes().Where(…)
快得多。因此,通过进行一系列有针对性的名称查找并避免查看所有类型,我解决了性能问题:

var result = AppDomain.CurrentDomain.GetAssemblies()
.Where(a => !a.IsDynamic)
.SelectMany(
            // possible full names is a list which tries replacing each . in the name with a +
            // starting from the end
    a => possibleFullNames.Select(t => new { t.@namespace, type = a.GetType(t.fullName) })
)
.Where(t => t.type != null);
在MSDN上构建您自己的自定义绑定器有一个困难,但我认为如果您试图从程序集范围内的每个程序集中加载每个类型,那么您将不得不忍受缓慢。当然,您可以始终使用并让.NET编译器为您处理所有类型查找。。。