How Func<DomainObject,object> return Object name as string [duplicate]
Asked Answered
J

3

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

Jennet answered 12/12, 2013 at 20:5 Comment(1)
You cannot with this signature -- it must be something such as Expression<Func<Student, object>>.Hierocracy
G
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));
    }  
Gignac answered 12/12, 2013 at 20:7 Comment(12)
This is good, but you have to tell him how to make it work. The OP has Func<>, not Expression.Harlan
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.Hierocracy
Also note that with a parameter of type Expression, you can't call it using a lambda.Gangway
@Harlan added some explanationGignac
@Hierocracy added some detailsGignac
Why cast it down to an Expression just so that you can cast it back up again to a LambdaExpression.Gangway
@Gangway in order to have one method accepting any type of expression as an argument. It could've been method group.Gignac
Are you sure about the MemberAccess clause? In particular, what would be the type of the first recursive subcall and why there is "." connecting two recursive subcalls?Amey
@WiktorZychla I wrote this code several years ago, let me check.Gignac
@WiktorZychla this should work in case of a=>a.p1.p2 and return p1.p2Gignac
Can't check it now but still, I am the only one who upvoted you ;)Amey
@WiktorZychla there is 2 ups and 1 downs :DGignac
A
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;
 }
Amey answered 12/12, 2013 at 20:17 Comment(0)
B
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"
Beniamino answered 12/12, 2013 at 20:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.