C# 使用表达式树复制属性值,转化为指定类型 ExpressionTree CopyProperties
之前使用的是网上的一个表达式树版本,使用时需要显示写出参数及返回值的类型 Tin TOut, 略显麻烦
public static class TransExpV2<TIn, TOut>
{
private static readonly Func<TIn, TOut> Func = GetFunc();
private static Func<TIn, TOut> GetFunc()
{
Type inType = typeof(TIn);
Type outType = typeof(TOut);
ParameterExpression parameterExpression = Expression.Parameter(inType, "inParam");
List<MemberBinding> memberBindingList = new List<MemberBinding>();
PropertyInfo[] inProperties = inType.GetProperties();
PropertyInfo[] outProperties = outType.GetProperties();
foreach (var inProp in inProperties)
{
foreach (var outProp in outProperties)
{
if (inProp.Name == outProp.Name)
{
if (outProp.CanWrite)
{
MemberExpression property = Expression.Property(parameterExpression, inProp);
MemberBinding memberBinding = Expression.Bind(outProp, property);
memberBindingList.Add(memberBinding);
}
break;
}
}
}
MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(outType), memberBindingList.ToArray());
Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[] { parameterExpression });
return lambda.Compile();
}
public static TOut Trans(TIn tIn)
{
return Func(tIn);
}
}
经过一点研究,决定还是使用另外一种使用缓存的版本,只用指定返回类型即可。效率比上面的代码略低,但比普通的反射还是要快不少。
静态类中声明以下方法及即可
static Dictionary<string, object> dicMappedFunc = new Dictionary<string, object>();
public static T ToMapped<T>(this object instance)
{
if (instance == null)
throw new ArgumentNullException();
Type instanceType = instance.GetType();
Type toType = typeof(T);
string key = $"{instanceType.FullName}-{toType.FullName}";
if (!dicMappedFunc.ContainsKey(key))
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "instance");
List<MemberBinding> memberBindingList = new List<MemberBinding>();
PropertyInfo[] instanceProps = instanceType.GetCacheProperties();
PropertyInfo[] toProps = toType.GetCacheProperties();
foreach (PropertyInfo insProp in instanceProps)
{
foreach (PropertyInfo toProp in toProps)
{
if (insProp.Name == toProp.Name)
{
if (toProp.CanWrite)
{
MemberExpression property = Expression.Property(Expression.Convert(parameterExpression, instanceType), insProp);
MemberBinding memberBinding = Expression.Bind(toProp, property);
memberBindingList.Add(memberBinding);
}
break;
}
}
}
MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(toType), memberBindingList.ToArray());
Expression<Func<object, T>> lambda = Expression.Lambda<Func<object, T>>(memberInitExpression, new ParameterExpression[] { parameterExpression });
Func<object, T> func = lambda.Compile();
dicMappedFunc[key] = func;
}
var function = (Func<object, T>)dicMappedFunc[key];
return function(instance);
}
使用时复制相同属性名的属性值,数据类型需相同

浙公网安备 33010602011771号