2013-12-12 8 views
6

Ich habe statische Methode wie folgt aus:Wie Func <Domainobject, object> Rückkehr Objektnamen als Zeichenfolge

public static string MyMethod(Func<Student, object> func) 
    {    
     return ??? ; 
    } 

und ich verwende es wie folgt:

var s1 = MyMethod(student => student.ID); // Return "ID" ??? 
    var s2 = MyMethod(student => student.Age); // Return "Age" ??? 
    var s3 = MyMethod(student => student.Name); // Return "Name" ??? 

Wie Schreibverfahren, das die folgenden Rück Ergebnisse ?

  • s1: "ID"
  • s2: "Alter"
  • s3: "Name"

* Rückkehr jeden property`s Namen nach => als String

+6

Sie können nicht mit dieser Unterschrift - Es muss etwas wie "Expression >" sein. – Jon

Antwort

1

Sie können die Signatur Ihrer Methode von

public static string MyMethod(Func<Student, object> func) 
ändern

Änderung es

public static string MyMethod(Expression<Func<Student, object>> func) { 
    return GetMemeberName(func) 
    } 

    public static string GetMemberName(Expression expression) 
    {    
     if (expression is LambdaExpression) 
     { 
      var lambdaExpression = (LambdaExpression)expression; 
      return GetMemberName(lambdaExpression.Body);        
     } 

     if (expression is MemberExpression) 
     { 
      var memberExpression = (MemberExpression)expression; 
      if (memberExpression.Expression.NodeType == ExpressionType.MemberAccess) 
      { 
       return GetMemberName(memberExpression.Expression)+ "."+ memberExpression.Member.Name; 
      } 
      return memberExpression.Member.Name; 
     } 

     if (expression is UnaryExpression) 
     { 
      var unaryExpression = (UnaryExpression)expression; 
      if (unaryExpression.NodeType != ExpressionType.Convert) 
       throw new Exception(string.Format(
        "Cannot interpret member from {0}", 
        expression)); 
      return GetMemberName(unaryExpression.Operand); 
     } 
     throw new Exception(string.Format("Could not determine member from {0}",expression)); 
    } 
+2

Das ist gut, aber du musst ihm sagen, wie es funktioniert. Das OP hat 'Func <>', nicht 'Expression'. – Gabe

+4

Im Grunde genommen handelt es sich hierbei um eine Menge Code, der, obwohl er nützlich ist, der Antwort auf die gestellte Frage nicht annähernd entspricht. Ich würde das erhöhen, wenn es zu einer echten Antwort gemacht würde. – Jon

+0

Beachten Sie auch, dass Sie mit einem Parameter vom Typ Expression nicht mit einem Lambda aufrufen können. – Servy

0

Die Signatur muss Ausdrucksbaum beinhalten anstatt func der Lage sein, um es zu inspizieren. Glücklicherweise ändern sich Ihre Aufrufe nicht, da der Compiler Ausdrücke aus Ihren lambdas erstellt.

Diese Version ist wahrscheinlich die kürzeste, es beinhaltet keine Rekursion, sondern funktioniert nur für einfache Eigenschaft Zugriff Lambda.

public static string MyFunc(Expression<Func<Student, object>> Property) 
{ 
    if (Property != null && Property.Body != null) 
     if (Property.Body.NodeType == ExpressionType.MemberAccess) 
     { 
      MemberExpression memberExpression = 
       (MemberExpression)Property.Body; 

      if (!string.IsNullOrEmpty(memberExpression.Member.Name)) 
       return memberExpression.Member.Name; 

     } 

    return string.Empty; 
} 
0

Von another SO question kann das sein, was Sie suchen:

public static string GetPropertyName<T>(Expression<Func<T>> propertyExpression) 
{ 
    return (propertyExpression.Body as MemberExpression).Member.Name; 
} 

es zu benutzen, Sie so etwas schreiben würde:

var propertyName = GetPropertyName(
    () => myObject.AProperty); // returns "AProperty"