开发过程中经常会遇到对象类型之间的转换映射,例如Model和ViewModel之间的映射绑定,下面总结几种常见的转换方式。事先准备两个类:
CheckFile
和 CheckFileModel
public class CheckFile
{
public string Id { get; set; }
public string FileTitle { get; set; }
public string Author { get; set; }
public DateTime? CreatTime;
}
public class CheckFileModel
{
public string Id { get; set; }
public string FileTitle { get; set; }
public string Author { get; set; }
public DateTime? CreatTime;
public string Source { get; set; }
}
CheckFile checkFile = new CheckFile
{
Id = "123",
FileTitle = "对象类型转换映射",
Author = "张三",
CreatTime = DateTime.Now
};
CheckFileModel fileModel = new CheckFileModel
{
Id = checkFile.Id,
FileTitle = checkFile.FileTitle,
Author = checkFile.Author,
CreatTime = checkFile.CreatTime
};
///
/// 泛型+反射
///
///
///
///
///
public static TOut TypeConvert<TOut, TIn>(TIn objIn)
{
Type tOut = typeof(TOut);
Type tIn = typeof(TIn);
TOut outModel = Activator.CreateInstance<TOut>();
// 属性赋值
foreach (var prop in tOut.GetProperties())
{
var propInfo = tIn.GetProperty(prop.Name);
if (propInfo != null)
{
var inValue = propInfo.GetValue(objIn);
prop.SetValue(outModel, inValue);
}
}
// 字段赋值
foreach (var field in tOut.GetFields())
{
var fieldInfo = tIn.GetField(field.Name);
if (fieldInfo != null)
{
var inValue = fieldInfo.GetValue(objIn);
field.SetValue(outModel, inValue);
}
}
return outModel;
}
///
/// Json序列化转换
///
///
///
///
///
public static TOut SerializeConvert<TOut, TIn>(TIn objIn)
{
string inString = JsonConvert.SerializeObject(objIn);
TOut outModel = JsonConvert.DeserializeObject<TOut>(inString);
return outModel;
}
///
/// AutoMapper序列化转换
///
///
///
///
///
public static TOut AutoMapperConvert<TOut, TIn>(TIn objIn)
{
// 初始化
Mapper.Initialize(n => n.CreateMap<TIn, TOut>());
TOut outModel = Mapper.Map<TIn, TOut>(objIn);
return outModel;
}
///
/// Expression表达式目录树转换
///
///
///
///
///
public static TOut ExpressionConvert<TOut, TIn>(TIn objIn)
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p");
List<MemberBinding> memberBindingList = new List<MemberBinding>();
// 绑定属性
PropertyInfo[] outPropertyInfos = typeof(TOut).GetProperties();
foreach (var prop in outPropertyInfos)
{
PropertyInfo inPropertyInfo = typeof(TIn).GetProperty(prop.Name);
if (inPropertyInfo != null)
{
MemberExpression property = Expression.Property(parameterExpression, inPropertyInfo);
MemberBinding memberBinding = Expression.Bind(prop, property);
memberBindingList.Add(memberBinding);
}
}
// 绑定字段
FieldInfo[] outFieldInfos = typeof(TOut).GetFields();
foreach (var field in outFieldInfos)
{
FieldInfo inFieldInfo = typeof(TIn).GetField(field.Name);
if (inFieldInfo != null)
{
MemberExpression fieldInfo = Expression.Field(parameterExpression, inFieldInfo);
MemberBinding memberBinding = Expression.Bind(field, fieldInfo);
memberBindingList.Add(memberBinding);
}
}
MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray());
Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[]
{
parameterExpression
});
Func<TIn, TOut> func = lambda.Compile();
return func.Invoke(objIn);
}
//----------------------------------------------------------
// 等价于构造一个下面的表达式
Expression<Func<CheckFile, CheckFileModel>> lambda = p => new CheckFileModel
{
Id = p.Id,
FileTitle = p.FileTitle,
Author = p.Author,
CreatTime = p.CreatTime
};
lambda.Compile().Invoke(checkFile);
表达式目录树
每个矩形框为一个节点(表达式类型),节点有多种类型,对于而这个 a*b+2 的几个节点:
Expression<Func<int, int, int>> exp1 = (a, b) => a * b+2;
//两个参数
ParameterExpression a = Expression.Parameter(typeof(int), "a");
ParameterExpression b = Expression.Parameter(typeof(int), "b");
//求积
BinaryExpression Multi=Expression.Multiply(a,b);
//常量
ConstantExpression x2 = Expression.Constant(2);
//求和
BinaryExpression Add = Expression.Add(Multi, x2);
//创建一个表示lambda表达式的对象
LambdaExpression lexp = Expression.Lambda<Func<int, int, int>>(Add, a, b);
//查看表达式
Console.WriteLine(lexp.ToString());
//简单使用
Expression<Func<int, int, int>> lexp = Expression.Lambda<Func<int, int, int>>(Add, a, b);
Func<int, int, int> fun = lexp.Compile();
Console.WriteLine(fun(3,5));
END |