Skip to content

Instantly share code, notes, and snippets.

@CharlieDigital
Created September 7, 2025 01:30
Show Gist options
  • Select an option

  • Save CharlieDigital/62cde4b1f62777ee0442d95935a43a1c to your computer and use it in GitHub Desktop.

Select an option

Save CharlieDigital/62cde4b1f62777ee0442d95935a43a1c to your computer and use it in GitHub Desktop.
C# Expression Paths
using System.Linq.Expressions;
List<string> MemberNames(Expression<Func<User, object>> u)
{
return ExpressionReader.GetNestedMemberNames(u);
}
Console.WriteLine(string.Join(".", MemberNames(u => u.UserProfile.HomeAddress.City)));
public class User
{
public int Id { get; set; }
public Profile UserProfile { get; set; }
public class Profile
{
public Address HomeAddress { get; set; }
}
public class Address
{
public string City { get; set; }
}
}
public static class ExpressionReader
{
public static List<string> GetNestedMemberNames<T, TValue>(
Expression<Func<T, TValue>> expression
)
{
var memberNames = new List<string>();
MemberExpression? memberExpression;
// Check if the expression is a UnaryExpression for boxing
if (
expression.Body is UnaryExpression unaryExpression
&& unaryExpression.Operand is MemberExpression unaryMember
)
{
memberExpression = unaryMember;
}
else if (expression.Body is MemberExpression member)
{
memberExpression = member;
}
else
{
throw new ArgumentException(
"Expression body must be a MemberExpression.",
nameof(expression)
);
}
// Walk the tree from the deepest member up to the root
while (memberExpression != null)
{
memberNames.Add(memberExpression.Member.Name);
memberExpression = memberExpression.Expression as MemberExpression;
}
// Reverse the list to get the correct order (e.g., "UserProfile.HomeAddress.City")
memberNames.Reverse();
return memberNames;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment