6

I have static method like this :

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

and I use it as following :

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

How write method that return the following results ?

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

* return each property`s name after => as string

R R
  • 313
  • 2
  • 4
  • 14
  • 6
    You cannot with this signature -- it must be something such as `Expression>`. – Jon Dec 12 '13 at 20:09

3 Answers3

1

You can change signature of your method from

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

change it to

  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));
    }  
vittore
  • 17,449
  • 6
  • 44
  • 82
0

The signature must involve expression tree rather than func to be able to inspect it. Luckily, your invocations don't change as the compiler will create expressions out of your lambdas.

This version is probably the shortest, it doesn't involve recursion but works only for simple property access lambdas.

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;
 }
Wiktor Zychla
  • 47,367
  • 6
  • 74
  • 106
0

From another SO question, this may be what you're looking for:

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

To use it, you'd write something like this:

var propertyName = GetPropertyName(
    () => myObject.AProperty); // returns "AProperty"
Community
  • 1
  • 1
Aaron Palmer
  • 8,912
  • 9
  • 48
  • 77