2014-03-05 157 views
0

我已经覆盖类中的属性,并希望读取自定义属性值,但它不起作用。任何人都可以解释为什么它不工作,以及如何解决问题?读取覆盖属性属性

public class Validator 
    { 


     [Serializable] 
     public class CollectionAttribute : Attribute 
     { 
      public virtual string[] Data { get; set; } 
      public string Default; 
     } 
} 

class Helpers 
    { 

     public static MemberInfo GetMemberInfo<T, TU>(Expression<Func<T, TU>> expression) 
     { 
      var member = expression.Body as MemberExpression; 
      if (member != null) 
       return member.Member; 

      throw new ArgumentException("Expression is not a member access", "expression"); 
     } 

     public static string GetName<T, TU>(Expression<Func<T, TU>> expression) 
     { 
      return GetMemberInfo(expression).Name; 
     } 

     public static string GetCollection<T, TU>(Expression<Func<T, TU>> expression) 
     { 
      var attribute = (Validator.CollectionAttribute[])GetMemberInfo(expression).GetCustomAttributes(typeof(Validator.CollectionAttribute), true); 
      return string.Join(",", attribute[0].Data); 
     } 
    } 

不工作。

public class TestClass:TestBaseClass 
    { 
     [Validator.Collection(Data = new[] { "doc", "docx", "dot", "dotx", "wpd", "wps", "wri" })] 
     public override string InputFormat { get; set; } 
    } 

    public class TestBaseClass 
    { 
     public virtual string InputFormat { get; set; } 
    } 

Helpers.GetCollection((TestClass p) => p.InputFormat) 
//The attribute variable in GetCollection method always null. It seems code looks for atribute in Base class. 

工作正常。

public class TestClass 
    { 
     [Validator.Collection(Data = new[] { "doc", "docx", "dot", "dotx", "wpd", "wps", "wri" })] 
     public override string InputFormat { get; set; } 
    } 

Helpers.GetCollection((TestClass p) => p.InputFormat) 

回答

1

InputFormat声明类型是TestBaseClass不具有该属性。而PropertyInfo返回的是声明类型,而不是参数的实际类型。

您需要做的是检索表达式参数的实际类型,然后返回该类型的PropertyInfo

public static MemberInfo GetMemberInfo<T, TU>(Expression<Func<T, TU>> expression) 
{ 
    var member = expression.Body as MemberExpression; 
    if (member != null) 
    { 
     // Getting the parameter's actual type, and retrieving the PropertyInfo for that type. 
     return expression.Parameters.First().Type.GetProperty(member.Member.Name); 
    } 

    throw new ArgumentException("Expression is not a member access", "expression"); 
}