C#反射:在成员字段上查找属性
我可能问得不对,但是您可以/如何在类本身中找到字段。。。例如C#反射:在成员字段上查找属性,c#,reflection,attributes,field,C#,Reflection,Attributes,Field,我可能问得不对,但是您可以/如何在类本身中找到字段。。。例如 public class HtmlPart { public void Render() { //this.GetType().GetCustomAttributes(typeof(OptionalAttribute), false); } } public class HtmlForm { private HtmlPart _FirstPart = new HtmlPart(); [Option
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();
}
公共类HtmlPart{
公共无效呈现(){
//this.GetType().GetCustomAttributes(typeof(OptionalAttribute),false);
}
}
公共类HtmlForm{
私有HtmlPart _FirstPart=新HtmlPart();
[可选]/您可以使用Type.GetFields
查找类中的字段,也可以使用MemberInfo.GetCustomAttributes
或IsDefined
查找应用于字段的属性-但是如果您需要查找特定类型的所有字段,您必须:
- 迭代所有要搜索的程序集
- 迭代每个程序集中的所有类型
- 迭代每个类型中的所有字段
- 检查每个字段的属性是否存在
现在,如果您真的想找出“某个特定属性是否应用于某个字段,该字段的值是对“this”对象的引用”那就更难了——因为你必须了解系统中每个对象的所有信息。你还应该记住,可能有两个字段都具有相同的值,即引用相同的对象。在这种情况下,对象是否算作“可选”
基本上,如果对象应该有属性(例如可选或不可选),那么该属性必须是对象本身的属性,而不是包含该属性的字段
这可能是因为我误解了您的意图,但我怀疑这要么不可行,要么至少不是一个好主意。您能在这里解释一下更大的情况吗?使用此属性您真正想要实现的是什么?下面是一个给定单个对象的示例,说明如何查找该对象上是否有任何公共或私有字段特定属性:
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);
}
}
对于问题的第二部分,您可以使用以下方法检查当前方法上是否定义了属性:
MethodInfo.GetCurrentMethod().IsDefined(typeof(ObsoleteAttribute));
编辑
若要回答“编辑是”,可以在不知道实际类型的情况下回答。以下函数接受一个类型参数并返回具有给定属性的所有字段。某个地方的某人将知道您要搜索的类型,或者将拥有您要搜索的类型的实例
否则,您将不得不按照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;
}
公共列表FindFields(类型,类型属性)
{
变量字段=新列表();
foreach(type.GetFields(BindingFlags.Public)中的var字段|
BindingFlags.NonPublic|
BindingFlags.Instance)
{
if(字段已定义(属性,true))
{
字段。添加(字段);
}
}
返回字段;
}
如果我正确理解了你的问题,我认为你想做的是不可能的
在Render
方法中,您希望获取应用于对象的可能属性。该属性属于属于类HtmlForm
的字段\u SecondPart
为此,必须将调用对象传递给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");
}
}
}
感谢您的回复-现在这更像是一个实验,而不是其他任何东西。我想知道这是否可能,因为这是一种尝试获取信息的奇怪方式。感谢-这似乎是“可能的”,但我再次认为,缺少的东西太多了,它无法工作。不,渲染方法完全可以访问typeof(HtmlForm)当然,如果HtmlForm本身是私有的,那么您可能需要通过Assembly.getExecutionGassembly().GetTypes().Where(t=>!t.IsGeneric&&!t.IsNested&&t.FullName==“MyNamespace.HtmlForm”)或类似的方式找到它。