首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何枚举所有具有自定义类属性的类?

如何枚举所有具有自定义类属性的类?
EN

Stack Overflow用户
提问于 2009-03-03 16:43:26
回答 8查看 100.9K关注 0票数 167

基于MSDN example的问题。

假设我们在独立的桌面应用程序中有一些带有HelpAttribute的C#类。是否可以枚举具有此类属性的所有类?以这种方式识别类有意义吗?自定义属性将用于列出可能的菜单选项,选择项将显示此类类的屏幕实例。类/项的数量将缓慢增长,但我认为这样我们就可以避免在其他地方枚举它们。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2009-03-03 16:49:32

是的,完全正确。使用反射:

代码语言:javascript
复制
static IEnumerable<Type> GetTypesWithHelpAttribute(Assembly assembly) {
    foreach(Type type in assembly.GetTypes()) {
        if (type.GetCustomAttributes(typeof(HelpAttribute), true).Length > 0) {
            yield return type;
        }
    }
}
票数 223
EN

Stack Overflow用户

发布于 2009-03-03 16:53:33

那么,您将不得不枚举加载到当前应用程序域中的所有程序集中的所有类。为此,您需要在当前应用程序域的AppDomain实例上调用GetAssemblies method

在那里,您可以在每个Assembly上调用GetExportedTypes (如果只想要公共类型)或GetTypes来获取程序集中包含的类型。

然后,在每个Type实例上调用GetCustomAttributes extension method,传递要查找的属性的类型。

您可以使用LINQ为您简化此过程:

代码语言:javascript
复制
var typesWithMyAttribute =
    from a in AppDomain.CurrentDomain.GetAssemblies()
    from t in a.GetTypes()
    let attributes = t.GetCustomAttributes(typeof(HelpAttribute), true)
    where attributes != null && attributes.Length > 0
    select new { Type = t, Attributes = attributes.Cast<HelpAttribute>() };

上面的查询将获得应用了属性的每个类型,以及分配给它的属性的实例。

请注意,如果将大量程序集加载到应用程序域中,则该操作的开销可能会很大。您可以使用Parallel LINQ来减少操作时间(以CPU周期为代价),如下所示:

代码语言:javascript
复制
var typesWithMyAttribute =
    // Note the AsParallel here, this will parallelize everything after.
    from a in AppDomain.CurrentDomain.GetAssemblies().AsParallel()
    from t in a.GetTypes()
    let attributes = t.GetCustomAttributes(typeof(HelpAttribute), true)
    where attributes != null && attributes.Length > 0
    select new { Type = t, Attributes = attributes.Cast<HelpAttribute>() };

根据特定的Assembly对其进行过滤非常简单:

代码语言:javascript
复制
Assembly assembly = ...;

var typesWithMyAttribute =
    from t in assembly.GetTypes()
    let attributes = t.GetCustomAttributes(typeof(HelpAttribute), true)
    where attributes != null && attributes.Length > 0
    select new { Type = t, Attributes = attributes.Cast<HelpAttribute>() };

如果程序集中包含大量类型,则可以再次使用并行LINQ:

代码语言:javascript
复制
Assembly assembly = ...;

var typesWithMyAttribute =
    // Partition on the type list initially.
    from t in assembly.GetTypes().AsParallel()
    let attributes = t.GetCustomAttributes(typeof(HelpAttribute), true)
    where attributes != null && attributes.Length > 0
    select new { Type = t, Attributes = attributes.Cast<HelpAttribute>() };
票数 117
EN

Stack Overflow用户

发布于 2013-02-06 07:30:31

其他答案参考GetCustomAttributes。添加此示例作为使用IsDefined的示例

代码语言:javascript
复制
Assembly assembly = ...
var typesWithHelpAttribute = 
        from type in assembly.GetTypes()
        where type.IsDefined(typeof(HelpAttribute), false)
        select type;
票数 37
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/607178

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档