6

This question already has an answer here:

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


  • You cannot with this signature -- it must be something such as Expression<Func<Student, object>>. - Jon

3 답변


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));
    }  


  • This is good, but you have to tell him how to make it work. The OP has Func<>, not Expression. - Gabe
  • Basically this is a bunch of code that, while useful, comes nowhere close to answering the stated question. I would upvote this if it were made into a real answer. - Jon
  • Also note that with a parameter of type Expression, you can't call it using a lambda. - Servy
  • @Gabe added some explanation - vittore
  • @Jon added some details - vittore

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;
 }


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"

Linked


Related

Latest