private static Func<object, object> CreateConverter<TBase,TSub>() where TSub : TBase, new()
{
var baseType = typeof(TBase);
var subType = typeof(TSub);
var baseParam = Expression.Parameter(type: typeof(object),name: "baseObj");
var base0bject = Expression.Convert(expression: baseParam, type: baseType);
var subVar = Expression.Variable(type: subType, name: "subObj");
var assignSubVar = Expression.Assign(left: subVar, right: Expression.New(type: subType));
var baseProperties = baseType.GetProperties(bindingAttr: BindingFlags.Public |
BindingFlags.Instance).Where(predicate: p => p.CanRead && p.CanWrite)ToArray();
var propertyAssignments = baseProperties.Select(selector: property =>
Expression.Assign(
left: Expression.Property(expression: subVar, propertyName: property.Name),
right: Expression.Property(expression: base0bject, propertyName: property.Name)
)
);
var block = Expression.Block(
variables: new[] { subVar },
expressions: assignSubVar,
Expression.Block(expressions: propertyAssignments),
Expression.Convert(expression: subVar,type: typeof(object))
);
var lambda = Expression.Lambda<Func<object, object>>(body: block, parameters: baseParam);
return lambda.Compile();
}