2012-10-01 113 views
1

我有以下的基礎上,中間和派生類下面::反射排除從基類和特定屬性的所有屬性與所有其他的派生類

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 } 

回答

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

您可以使用下面的函數來獲得期望的結果: 在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
var properties = new List<PropertyInfo>(); 

GetProps(typeof(MostDerived), properties); 

GetProps是一個遞歸函數,它獲取聲明類型的屬性,然後爲層次結構中的下一個類型調用自身。它停止當它到達「基地」

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性質。

相關問題