C#reflection:在成员字段上查找属性
我可能会错误地问这个问题,但是可以/如何在一个类中查找字段…例如……
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(); }
或者我可能只是错误地执行此操作…如何调用方法然后检查应用于自身的属性?
另外,为了这个问题 – 我很好奇是否有可能在不知道/访问父类的情况下找到属性信息!
如果我理解你的问题,我认为你想要做的事情是不可能的……
在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"); } } }
以下是给定单个对象如何查找该对象上的任何公共或私有字段是否具有特定属性的示例:
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 FindFields(Type type, Type attribute) { var fields = new List (); foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { if (field.IsDefined(attribute, true)) { fields.Add(field); } } return fields; }
您可以使用Type.GetFields
在类中查找字段,并且可以使用MemberInfo.GetCustomAttributes
或IsDefined
查找应用于字段的属性 – 但如果您需要查找特定类型的所有字段,则必须:
- 迭代要搜索的所有程序集
- 迭代每个程序集中的所有类型
- 迭代每种类型中的所有字段
- 检查每个字段的属性是否存在
现在,如果你真的试图找出“是一个特定属性应用于一个值为’this’对象的引用的字段”那么那就更难了 – 因为你必须知道系统中每个对象的所有内容。 您还应该记住,可能有两个具有相同值的字段,即引用相同的对象。 在这种情况下,对象是否会被视为“可选”?
基本上,如果对象应该具有属性(例如可选或不可选),那么它必须是对象本身的属性,而不是包含属性的字段。
可能是我误解了你想要做的事情,但我怀疑它要么不可行,要么至少不是个好主意。 你能解释一下这里的大局吗? 你真的想通过这个属性实现什么?