Get Name of Nested Property as String Value

I presented a method to retrieve the property name referenced by a lambda expression in a previous post.

Reader Jacek asked,

is there any way for nested property (eg. Studies.ID or Studies.Class.Name) to convert to string?

Nice question, and I tried to solve it.

Starting with a simple data model

public class Foo
  public int FooID { get; set; }
  public string Name { get; set; }
public class Bar
  public string Name { get; set; }
  public Foo BarFoo { get; set; }
public class Baz
  public string Name { get; set; }
  public Bar BazBar { get; set; }

we want to convert an expression such as b => b.BazBar.BarFoo.Name into its string representation.

public static string GetPropertyName(this LambdaExpression expression)

First, we handle type casts, as in the original solution:

  if (expression.Body is UnaryExpression)
    UnaryExpression unex = (UnaryExpression)expression.Body;
    if (unex.NodeType == ExpressionType.Convert)
      Expression ex = unex.Operand;
      MemberExpression mex = (MemberExpression)ex;
      return mex.Member.Name;

Keep a reference of the parameter, and set path (i.e. concatenated property names) to empty

  MemberExpression memberExpression = (MemberExpression)expression.Body;
  MemberExpression memberExpressionOrg = memberExpression;

  string Path = "";

The sequence b.BazBar.BarFoo is stored as an expression of ExpressionType MemberAccess, which is an object of the non-public class System.Reflection.RuntimePropertyInfo (google), as the debugger tells us.

Since the class is not public, we need to access the Member property using reflection, in this case PropertyInfo.GetValue:

  while (memberExpression.Expression.NodeType == ExpressionType.MemberAccess)
    var propInfo = memberExpression.Expression
    var propValue = propInfo.GetValue(memberExpression.Expression, null) 
      as PropertyInfo;
    Path = propValue.Name + "." + Path;

    memberExpression = memberExpression.Expression as MemberExpression;

  return Path + memberExpressionOrg.Member.Name;

The variable Path stores the sequence of property names as we iterate through the expression tree. Finally, the last property name is added.

Using this code, the line

    (Expression<Func<Baz, string>>)(b => b.BazBar.BarFoo.Name)));

produces this output:


2 Responses to Get Name of Nested Property as String Value

  1. […] and the GetPropertyName() extension method as previously defined. […]

  2. […] on my code to retrieve property names from LinQ expressions, I wrote an extension method to retrieve the attribute names using the AttributeLogicalName […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: