我有以下基础,中间和派生类::
public class Base
{
[DataMemberAttribute()]
public int ValueBase { get; set; }
[IgnoreForAllAttribute("Param1", "Param2")]
public int IgnoreBase { get; set; }
}
public class Middle : Base
{
[DataMemberAttribute()]
public int ValueMiddle { get; set; }
[IgnoreForAllAttribute("Param1", "Param2")]
public int IgnoreMiddle { get; set; }
}
public class MostDerived : Middle
{
[DataMemberAttribute()]
public int ValueMostDerived { get; set; }
[IgnoreForAllAttribute("Param1", "Param2")]
public int IgnoreMostDerived { get; set; }
}
我需要一个给定类型的函数,我需要为层次结构中除基础之外的所有类返回DataMemberAttribute属性。
此外,应该忽略图中所有类的所有IgnoreForAllAttribute属性。
var derivedObject = new MostDerived();
var attributes = MyShinyAttributeFunction(derivedObject.GetType());
// returns [] { ValueMostDerived, ValueMiddle }
答案 0 :(得分:6)
这是一个LINQ示例,它假定DateMemberAttribute和IgnoreForAllAttribute是互斥的
IEnumerable<PropertyInfo> MyProperties(object o)
{
o.GetType().GetProperties()
.Where(p => !(p.DeclaringType is Base))
.Where(p => p.GetCustomAttributes(false).Any(a => a is DataMemberAttribute)
}
假设属性不相互排斥的样本
IEnumerable<PropertyInfo> MyProperties(object o)
{
o.GetType().GetProperties()
.Where(p => !(p.DeclaringType is Base))
.Where(p =>
{
var attributes = p.GetCustomAttributes(false);
return attributes.Any(a => a is DataMemberAttribute)
&& !attributes.Any(a => a is IgnoreForAllAttribute);
}
}
答案 1 :(得分:3)
var properties = new List<PropertyInfo>();
GetProps(typeof(MostDerived), properties);
GetProps是一个递归函数,它获取声明类型的属性,然后为层次结构中的下一个类型调用自身。它到达'Base'时会停止
private static void GetProps(Type T, List<PropertyInfo> Properties)
{
if (T != typeof(Base))
{
var pis = T.GetProperties();
foreach (var pi in pis)
{
if (pi.DeclaringType == T &&
pi.GetCustomAttribute<DataMemberAttribute>() != null &&
pi.GetCustomAttribute<IgnoreForAllAttribute>() == null)
{
Properties.Add(pi);
}
}
GetProps(T.BaseType, Properties);
}
}
属性列表将包含具有DataMemberAttribute但没有IgnoreForAllAttribute的属性。
答案 2 :(得分:1)
您可以使用以下功能获得所需的结果: 在propertyNames中,您将获得所需的属性。
用法:
List<string> propertyNames = new List<string>();
List<string> basePropertyNames = new List<string>();
MyShinyAttributeFunction(derivedObject.GetType(), ref propertyNames, ref basePropertyNames);
功能:
void MyShinyAttributeFunction(Type type, ref List<string> propertyNames, ref List<string> basePropertyNames)
{
if (type == null)
return;
MyShinyAttributeFunction(type.BaseType, ref propertyNames, ref basePropertyNames);
foreach (var property in type.GetProperties())
{
foreach (object customAttr in property.GetCustomAttributes(false))
{
if (customAttr is DataMemberAttribute)
{
if (type.BaseType.Name.Equals("Object"))
{
DataMemberAttribute attribute = (DataMemberAttribute)customAttr;
if (!basePropertyNames.Contains(property.Name))
basePropertyNames.Add(property.Name);
}
else
{
DataMemberAttribute attribute = (DataMemberAttribute)customAttr;
if (!propertyNames.Contains(property.Name) && !basePropertyNames.Contains(property.Name))
propertyNames.Add(property.Name);
}
}
}
}
}
答案 3 :(得分:0)
您必须使用以下内容:
当BaseType不存在时停止的递归函数应该可以解决问题。