2012-06-04 4 views
4

object에서 사용자 지정 특성을 가져 오려고하면이 함수는 null을 반환합니다. 왜?개체의 사용자 지정 특성 얻기

class Person 
{ 
    [ColumnName("first_name")] 
    string FirstName { get; set; } 

    Person() 
    { 
     FirstName = "not important"; 
     var attrs = AttributeReader.Read(FirstName); 
    } 
} 

static class AttributeReader 
{ 
    static object[] Read(object column) 
    { 
     return column.GetType().GetCustomAttributes(typeof(ColumnNameAttribute), false); 
    } 
} 
+0

FirstName을 공개하려고 했습니까? – daryal

+0

코드는 내가하려는 일의 일반적인 예일뿐입니다. – mooper

+0

'var attrs = AttributeReader.Read (FirstName);가 아닌'var attrs = AttributeReader.Read (Person);'을 호출하는 것을 의미하지 않습니까? – ProfK

답변

14

당신은 그 방법에 string, "not important"을 전달하고 있습니다. 따라서 Typetypeof(string)입니다. 어느 에는 그 속성이 없습니다. 또한 Person에도 해당 속성이 없습니다. MemberInfo (FirstName) 만 있습니다.

public static ColumnNameAttribute[] Read<T>(Expression<Func<T>> func) 
{ 
    var member = func.Body as MemberExpression; 
    if(member == null) throw new ArgumentException(
     "Lambda must resolve to a member"); 
    return (ColumnNameAttribute[])Attribute.GetCustomAttributes(
     member.Member, typeof(ColumnNameAttribute), false); 
} 

그러나

var attrs = AttributeReader.Read(() => FirstName); 

과 :

Expression를 전달하여 그 일의 방법이있다! 나는 Person 생성자가이 위치에 적절한 지 확신 할 수 없다고 조언해야한다. 캐싱이 필요할 것 같습니다.

당신은 그 전달 람다를 사용하지 않으면 Type 및 멤버 이름은, 너무 일 것 즉

var attrs = AttributeReader.Read(typeof(Person), "FirstName"); 

(그리고 거기에서 반사 할) - 또는 더를 위해 (제네릭과 혼합하지를 진짜 이유) :

var attrs = Attribute.Read<Person>("FirstName"); 
+0

감사합니다. – mooper

+0

@Segfault 제 경고문은 여전히 ​​적용됩니다. 개인적으로 * 객체 생성자 근처의 코드 *를 허용하지 않습니다. –

+0

그래, 코드를 가능한 한 명확하게 만드는 동안 내가하려고했던 것을 보여 주려고했다. – mooper