using System.Collections.Generic;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
public static void Main()
Expression<Func<ParentType, object>> columns = x => new
Console.WriteLine("Before:" + columns.Body);
Console.WriteLine("------------------------------------------------------------------");
var transform = columns.Transform<ParentType, ParentType>();
Console.WriteLine("After:" + transform.Body);
Console.WriteLine("------------------------------------------------------------------");
Console.WriteLine("------------------------------------------------------------------");
Console.WriteLine("Done!");
public static class Extensions
public static bool IsAnonymousType(this Type type)
var markedWithAttribute = type.GetCustomAttributes(typeof (CompilerGeneratedAttribute), inherit: false).Any();
var typeName = type.Name;
return markedWithAttribute && (typeName.StartsWith("<>") || type.Name.StartsWith("VB$")) && typeName.Contains("AnonymousType");
public static ConstructorInfo GetPrivateConstructor(this Type type)
return type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
public static Expression<Func<Tin, Tout>> Transform<Tin, Tout>(this Expression<Func<Tin, object>> source)
var visitor = new ReturnTypeVisitor<Tin, Tout>();
var result = (Expression<Func<Tin, Tout>>)visitor.Visit(source);
public class ReturnTypeVisitor<TIn, TOut> : ExpressionVisitor
private readonly Type funcToReplace;
private ParameterExpression currentParameter;
private ParameterExpression defaultParameter;
private Type currentType;
public ReturnTypeVisitor()
funcToReplace = typeof (Func<, >).MakeGenericType(typeof (TIn), typeof (object));
protected override Expression VisitNew(NewExpression node)
if (!node.Type.IsAnonymousType())
return base.VisitNew(node);
currentType = typeof (TOut);
var ctor = currentType.GetPrivateConstructor();
return base.VisitNew(node);
NewExpression expr = Expression.New(ctor);
IEnumerable<MemberBinding> bindings = node.Members.Select(x =>
var mi = currentType.GetProperty(x.Name);
if (((PropertyInfo)x).PropertyType.IsAnonymousType())
var property = (PropertyInfo)x;
var parentType = currentType;
var parentParameter = currentParameter;
currentType = currentType.GetProperty(property.Name).PropertyType;
currentParameter = Expression.Parameter(currentType, currentParameter.Name + "." + property.Name);
var xOriginal = VisitNew(node.Arguments.FirstOrDefault(a => a.Type == property.PropertyType) as NewExpression);
currentType = parentType;
currentParameter = parentParameter;
return (MemberBinding)Expression.Bind(mi, xOriginal);
var xOriginal = Expression.PropertyOrField(currentParameter, x.Name);
return (MemberBinding)Expression.Bind(mi, xOriginal);
return Expression.MemberInit(expr, bindings);
protected override Expression VisitLambda<T>(Expression<T> node)
if (typeof (T) != funcToReplace)
return base.VisitLambda(node);
defaultParameter = node.Parameters.First();
currentParameter = defaultParameter;
var body = Visit(node.Body);
return Expression.Lambda<Func<TIn, TOut>>(body, defaultParameter);