public static TOut Copy<TIn, TOut>(TIn source) where TOut : new()
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "source");
MemberInitExpression memberInitExpression = Expression.MemberInit(
Expression.New(typeof(TOut)),
(from property in typeof(TOut).GetProperties()
where property.CanWrite
from sourceProperty in typeof(TIn).GetProperties()
where sourceProperty.Name == property.Name && sourceProperty.PropertyType == property.PropertyType
select Expression.Bind(property, Expression.Property(parameterExpression, sourceProperty))).ToArray()
);
Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, parameterExpression);
return lambda.Compile()(source);
}