C#反射:在成员字段上查找属性

时间:2009-04-29 16:36:25

标签: c# reflection attributes field

我可能会错误地提出这个问题,但是可以/如何在自己内部的类中找到字段...例如......

public class HtmlPart {
  public void Render() {
    //this.GetType().GetCustomAttributes(typeof(OptionalAttribute), false);
  }
}

public class HtmlForm {
  private HtmlPart _FirstPart = new HtmlPart();      
  [Optional] //<-- how do I find that?
  private HtmlPart _SecondPart = new HtmlPart();
}

或者我可能只是错误地执行此操作...如何调用方法然后检查应用于自身的属性?

另外,为了问题 - 我很好奇是否有可能在不知道/访问父类的情况下找到属性信息

3 个答案:

答案 0 :(得分:13)

如果我理解你的问题,我认为你想做的事情是不可能的......

Render方法中,您希望获取应用于对象的可能属性。该属性属于属于_SecondPart类的字段HtmlForm

要使其工作,您必须将调用对象传递给Render方法:

    public class HtmlPart {
        public void Render(object obj) {
            FieldInfo[] infos = obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

            foreach (var fi in infos)
            {
                if (fi.GetValue(obj) == this && fi.IsDefined(typeof(OptionalAttribute), true))
                    Console.WriteLine("Optional is Defined");
            }
        }
    }

答案 1 :(得分:10)

以下是给定单个对象如何查找该对象上的任何公共或私有字段是否具有特定属性的示例:

var type = typeof(MyObject);
foreach (var field in type.GetFields(BindingFlags.Public |
             BindingFlags.NonPublic | BindingFlags.Instance))
{
    if (field.IsDefined(typeof(ObsoleteAttribute), true))
    {
        Console.WriteLine(field.Name);
    }

}

对于问题的第二部分,您可以使用以下方法检查当前方法中的属性是否为defiend:

MethodInfo.GetCurrentMethod().IsDefined(typeof(ObsoleteAttribute));

修改

要回答您的编辑,可以在不知道实际类型的情况下进行。以下函数采用类型Parameter并返回具有给定属性的所有字段。某个地方的某个人要么知道你要搜索的类型,要么会有你要搜索的类型的实例。

如果不这样做,你就必须像Jon Skeet所说的那样枚举一个程序集中的所有对象。

   public List<FieldInfo> FindFields(Type type, Type attribute)
    {
        var fields = new List<FieldInfo>();
        foreach (var field in type.GetFields(BindingFlags.Public |
                           BindingFlags.NonPublic |
                           BindingFlags.Instance))
        {
            if (field.IsDefined(attribute, true))
            {
                fields.Add(field);
            }

        }
        return fields;
    }

答案 2 :(得分:5)

您可以使用Type.GetFields查找班级中的字段,并且可以使用MemberInfo.GetCustomAttributesIsDefined找到应用于字段的属性 - 但是如果您需要找到a的所有字段特殊类型,你将不得不:

  • 迭代您要搜索的所有程序集
  • 迭代每个程序集中的所有类型
  • 迭代每种类型中的所有字段
  • 检查每个字段的属性是否存在

现在,如果你真的试图找出“是一个特定的属性应用于一个值为'this'对象的引用的字段”那么那就更难了 - 因为你必须知道关于每个对象的所有内容在系统中。您还应该记住,可能存在具有相同值的两个字段,即引用相同的对象。在这种情况下,对象是否会被视为“可选”?

基本上,如果对象应该具有属性(例如可选或不可选),那么它必须是对象本身的属性,而不是包含属性的字段。

可能是因为我误解了你想要做的事情,但我怀疑它要么不可行,要么至少不是个好主意。你能解释一下这里的大局吗?你真的想通过这个属性实现什么目标?