我有一个自定义属性BacksCache
,我用它来标记类中的字段,当满足某些条件时需要“默认”。
我正在使用以下代码:
Type type = obj.GetType();
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy);
foreach (FieldInfo field in fields)
{
foreach (Attribute at in field.GetCustomAttributes(true))
if (at is BacksCache)
{
field.SetValue(obj, Utils.DefaultValue(field.FieldType));
}
}
如果类继承层次结构是扁平的,则此代码可以正常工作。也就是说,如果type
是声明所有属性字段的类型,那么一切都很棒。只要我有一个班级A
从哪个下级班B
(B : A
)和B
有一些属性字段就会崩溃:只有{{1}声明的字段检测到并“默认”。
相关字段为A
或private
,如果这有任何区别。
有关如何解决此问题的任何想法?
答案 0 :(得分:7)
请注意BindingFlags.FlattenHierarchy选项的小字体:
指定public和protected 层次结构中的静态成员应该 被退回私有静态成员 在继承的类中不是 返回即可。静态成员包括 字段,方法,事件和 属性。嵌套类型不是 返回。
粗体短语中的“静态”单词是oops,不返回私有成员。要解决此问题,您需要通过Type.BaseType向上移动继承链。
答案 1 :(得分:2)
你的措辞有点令人困惑,哪个类是基类A或B?您要反映哪一个,基类或派生类。我问,因为我在复制你的问题时遇到了麻烦。我试过这个并且工作正常:
static void Main(string[] args)
{
foreach (var prop in typeof(Sub).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy))
{
foreach (var attrib in prop.GetCustomAttributes(typeof(DescriptionAttribute), false))
{
Console.WriteLine(prop.Name);
}
}
Console.ReadKey(true);
}
public class Base
{
[Description]
public int IntProp { get; set; }
}
public class Sub : Base
{
[Description]
public string StringProp { get; set; }
}
输出正确,它显示两个属性。
此外,我刚刚注意到你正在处理菲尔兹。我这样做了,仍然得到了正确的输出:
static void Main(string[] args)
{
foreach (var prop in typeof(Sub).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy))
{
foreach (var attrib in prop.GetCustomAttributes(typeof(DescriptionAttribute), false))
{
Console.WriteLine(prop.Name);
}
}
Console.ReadKey(true);
}
public class Base
{
[Description]
public int X;
[Description]
public int IntProp { get; set; }
}
public class Sub : Base
{
[Description]
public int Y;
[Description]
public string StringProp { get; set; }
}
X和Y都输出到控制台。
答案 2 :(得分:0)
Attribute.GetCustomAttributes
将搜索继承的值。给出你的例子的代码是:
foreach (Attribute at in Attribute.GetCustomAttributes(field, true))
{
// Test and set here
}
有关详细说明,请参阅Weitao Su's post on GetCustomAttributes。