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
      .GetType().GetProperty("Member");
    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

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

produces this output:

BazBar.BarFoo.Name

2 thoughts on “Get Name of Nested Property as String Value

  1. Pingback: Deployment Checks for Configuration Data « devioblog

  2. Pingback: Retrieving the Attribute Names of CRM 2011 Entities « devioblog

Leave a Reply

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

WordPress.com Logo

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

Facebook photo

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

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.