C# 使用反射获取 MemberInfo 的类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15921608/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 18:28:01  来源:igfitidea点击:

Getting the type of a MemberInfo with reflection

c#.netreflectionattributescustom-attributes

提问by GrandMasterFlush

I'm using reflection to load a treeview with the class structure of a project. Each of the members in a class have a custom attribute assigned to them.

我正在使用反射加载具有项目类结构的树视图。类中的每个成员都有一个分配给他们的自定义属性。

I don't have a problem getting the attributes for a class using MemberInfo.GetCustomAttributes()however I need a way of working out if a class member is a custom class and then needs parsing itself to return the custom attributes.

我使用获取类的属性没有问题,MemberInfo.GetCustomAttributes()但是我需要一种方法来确定类成员是否是自定义类,然后需要解析自身以返回自定义属性。

So far, my code is:

到目前为止,我的代码是:

MemberInfo[] membersInfo = typeof(Project).GetProperties();

foreach (MemberInfo memberInfo in membersInfo)
{
    foreach (object attribute in memberInfo.GetCustomAttributes(true))
    {
        // Get the custom attribute of the class and store on the treeview
        if (attribute is ReportAttribute)
        {
            if (((ReportAttribute)attribute).FriendlyName.Length > 0)
            {
               treeItem.Items.Add(new TreeViewItem() { Header = ((ReportAttribute)attribute).FriendlyName });
            }
        }
        // PROBLEM HERE : I need to work out if the object is a specific type
        //                and then use reflection to get the structure and attributes.
    }
}

Is there an easy way of getting the target type of a MemberInfo instance so I can handle it appropriately? I feel I'm missing something obvious but I'm going round in circles at the minute.

有没有一种简单的方法可以获取 MemberInfo 实例的目标类型,以便我可以适当地处理它?我觉得我错过了一些明显的东西,但我现在正在绕圈子。

采纳答案by Daniel Hilgarth

GetPropertiesreturns an array of PropertyInfoso you should use that.
Then it is simply a matter of using the PropertyTypeproperty.

GetProperties返回一个数组,PropertyInfo所以你应该使用它。
那么这只是一个使用PropertyType属性的问题。

PropertyInfo[] propertyInfos = typeof(Project).GetProperties();

foreach (PropertyInfo propertyInfo in propertyInfos)
{
    // ...
    if(propertyInfo.PropertyType == typeof(MyCustomClass))
        // ...
}

回答by nawfal

I think you can get better performance if you carry around this extension method:

我认为如果你采用这种扩展方法,你可以获得更好的性能:

public static Type GetUnderlyingType(this MemberInfo member)
{
    switch (member.MemberType)
    {
        case MemberTypes.Event:
            return ((EventInfo)member).EventHandlerType;
        case MemberTypes.Field:
            return ((FieldInfo)member).FieldType;
        case MemberTypes.Method:
            return ((MethodInfo)member).ReturnType;
        case MemberTypes.Property:
            return ((PropertyInfo)member).PropertyType;
        default:
            throw new ArgumentException
            (
             "Input MemberInfo must be if type EventInfo, FieldInfo, MethodInfo, or PropertyInfo"
            );
    }
}

Should work for any MemberInfo, not just PropertyInfo. You may avoid MethodInfofrom that list since its not under lying type per se (but return type).

应该适用于任何人MemberInfo,而不仅仅是PropertyInfo. 您可以避免MethodInfo使用该列表,因为它本身不是底层类型(但返回类型)。

In your case:

在你的情况下:

foreach (MemberInfo memberInfo in membersInfo)
{
    foreach (object attribute in memberInfo.GetCustomAttributes(true))
    {
        if (attribute is ReportAttribute)
        {
            if (((ReportAttribute)attribute).FriendlyName.Length > 0)
            {
               treeItem.Items.Add(new TreeViewItem() { Header = ((ReportAttribute)attribute).FriendlyName });
            }
        }

        //if memberInfo.GetUnderlyingType() == specificType ? proceed...
    }
}

I wonder why this hasn't been part of BCL by default.

我想知道为什么默认情况下这不是 BCL 的一部分。