2013-06-14 3 views
9

로 전달 된 매개 변수의 PropertyInfo를 가져, 나는 수업이 있습니다람다 식 예를 들어

public class Person 
{ 
    public int Id; 
    public string Name, Address; 
} 

을 나는 아이디에이 클래스 기반의 정보를 업데이트하는 방법을 호출 할 :

update(myId, myPerson => myPerson.Name = "abc"); 

설명 :이 방법은 MYID 주어진 데이터베이스에서 쿼리 Person 개체를 얻을 것이다, 그것은 Name에 "ABC"를 설정하고, 그래서이 전화로 동일한 작업을 수행 :

update(myId, myPerson => myPerson.Address = "my address"); 

가능합니까? 그렇다면 어떻게?

답변

4

가능하며 PropertyInfo을 사용할 필요가 없습니다.

당신은 너무처럼 방법을 설계하는 것 :

public bool Update<T>(int id, Action<T> updateMethod) 
    // where T : SomeDbEntityType 
{ 
    T entity = LoadFromDatabase(id); // Load your "person" or whatever 

    if (entity == null) 
     return false; // If you want to support fails this way, etc... 

    // Calls the method on the person 
    updateMethod(entity); 

    SaveEntity(entity); // Do whatever you need to persist the values 

    return true; 
} 
+0

덕분에, 내가 :) 감사 –

20

내가, PropertyInfo를 사용하지하는 것과 같은 Reed Copsey는 그의 대답에 말했지만, 단지 정보, 당신이 가진 표현의 PropertyInfo을 추출 할 수 있습니다 :

public PropertyInfo GetPropertyFromExpression<T>(Expression<Func<T, object>> GetPropertyLambda) 
{ 
    MemberExpression Exp = null; 

    //this line is necessary, because sometimes the expression comes in as Convert(originalexpression) 
    if (GetPropertyLambda.Body is UnaryExpression) 
    { 
     var UnExp = (UnaryExpression)GetPropertyLambda.Body; 
     if (UnExp.Operand is MemberExpression) 
     { 
      Exp = (MemberExpression)UnExp.Operand; 
     } 
     else 
      throw new ArgumentException(); 
    } 
    else if (GetPropertyLambda.Body is MemberExpression) 
    { 
     Exp = (MemberExpression)GetPropertyLambda.Body; 
    } 
    else 
    { 
     throw new ArgumentException(); 
    } 

    return (PropertyInfo)Exp.Member; 
} 
MyPerson.PersonData.PersonID 같은 복합 식의 경우

, 당신은 서브 표현식을 받고 갈 수있다 더 이상 MemberExpressions이 아닐 때까지 신속하게 리드 Copsey을 지원하기위한

public PropertyInfo GetPropertyFromExpression<T>(Expression<Func<T, object>> GetPropertyLambda) 
{ 
    //same body of above method without the return line. 
    //.... 
    //.... 
    //.... 

    var Result = (PropertyInfo)Exp.Member; 

    var Sub = Exp.Expression; 

    while (Sub is MemberExpression) 
    { 
     Exp = (MemberExpression)Sub; 
     Result = (PropertyInfo)Exp.Member; 
     Sub = Exp.Expression; 
    } 

    return Result; 
    //beware, this will return the last property in the expression. 
    //when using GetValue and SetValue, the object needed will not be 
    //the first object in the expression, but the one prior to the last. 
    //To use those methods with the first object, you will need to keep 
    //track of all properties in all member expressions above and do 
    //some recursive Get/Set following the sequence of the expression. 
} 
+0

수정 :이 ArgumentExeption에 오타 (ArgumentException이 있어야한다)입니다 ... 그리고 서브가 사용되지 않습니다. 하지만 여전히 멋진 것들! :) – Jowen

+0

작업 할 때 하위가 필요합니다. 복합 표현 인 경우에만 가져옵니다. –