2013-06-14 23 views
9

olarak geçirilen bir parametrenin PropertyInfo alın, bir sınıf var:lambda ifadesi Örneğin

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

ve ben Id bu sınıf tabanında bilgi güncellemek için bir yöntemi çağırmak istiyorum:

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

açıklamak: Bu yöntem bir MyID verilen veritabanından sorgulamak ve Person varlık alır olacak, o zaman Name için "abc" ayarlar, bu yüzden bu isimle aynı işi yapar:

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

Bu mümkün mü? Öyleyse nasıl?

cevap

4

Bu, PropertyInfo kullanılmasına gerek yoktur.

Çok sevdiği yöntem tasarım ediyorum:

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

sayesinde ben :) takdir –

20

Ben PropertyInfo kullanmak ister gibi Reed Copsey onun cevabını söyledi, ama sadece bilgi için, bununla bir ifadenin PropertyInfo çıkarabilir :

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 gibi kompozit ifade durumunda

, sen alt ifadeleri alma gidebiliriz Artık MemberExpressions değiller. hızla Reed Copsey desteklemek için

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

Düzeltme: orada ArgumentExeption bir yazım hatası (ArgumentException olmalıdır) ... ve Alt hiçbir zaman kullanılmaz. Ama yine de havalı şeyler! :) – Jowen

+0

Çalışırken ihtiyacım vardı, sadece bileşik bir ifade ise oraya gider. –