2013-12-12 10 views
6

Ho metodo statico come questo:Come Func <DomainObject, object> nome ritorno dell'oggetto come stringa

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

e lo uso come segue:

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

metodo Come scrittura che restituiscono il seguente risultati?

  • s1: "ID"
  • s2: "Age"
  • s3: "Nome"

* ritorno ogni nome property`s dopo => come stringa

+6

Non è possibile con questa firma - deve essere qualcosa come 'Espressione >'. – Jon

risposta

1

È possibile modificare la firma del metodo da

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

cambiamento a

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

Questo è buono, ma devi dirgli come farlo funzionare. L'OP ha 'Func <>', non 'Expression'. – Gabe

+4

Fondamentalmente questo è un mucchio di codice che, sebbene utile, non arriva da nessuna parte per rispondere alla domanda indicata. Avrei votato questo se fosse stato trasformato in una vera risposta. – Jon

+0

Si noti inoltre che con un parametro di tipo 'Expression', non è possibile chiamarlo utilizzando un lambda. – Servy

0

La firma deve coinvolgere albero di espressione, piuttosto che func per essere in grado di visitarlo. Fortunatamente, le tue invocazioni non cambiano in quanto il compilatore creerà espressioni dai tuoi lambda.

Questa versione è probabilmente la più corta, non comporta la ricorsione ma funziona solo per i lambda di accesso alle proprietà semplici.

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

Da another SO question, questo può essere quello che stai cercando:

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

Per usarlo, devi scrivere qualcosa di simile:

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