開發過程中經常會遇到對象類型之間的轉換映射,例如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; }
}
1. 強類型賦值綁定
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
};
2. 泛型+反射
/// <summary>
/// 泛型+反射
/// </summary>
/// <typeparam name="TOut"></typeparam>
/// <typeparam name="TIn"></typeparam>
/// <param name="objIn"></param>
/// <returns></returns>
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;
}
3. Json序列化轉換
/// <summary>
/// Json序列化轉換
/// </summary>
/// <typeparam name="TOut"></typeparam>
/// <typeparam name="TIn"></typeparam>
/// <param name="objIn"></param>
/// <returns></returns>
public static TOut SerializeConvert<TOut, TIn>(TIn objIn)
{
string inString = JsonConvert.SerializeObject(objIn);
TOut outModel = JsonConvert.DeserializeObject<TOut>(inString);
return outModel;
}
4. AutoMapper序列化轉換
/// <summary>
/// AutoMapper序列化轉換
/// </summary>
/// <typeparam name="TOut"></typeparam>
/// <typeparam name="TIn"></typeparam>
/// <param name="objIn"></param>
/// <returns></returns>
public static TOut AutoMapperConvert<TOut, TIn>(TIn objIn)
{
// 初始化
Mapper.Initialize(n => n.CreateMap<TIn, TOut>());
TOut outModel = Mapper.Map<TIn, TOut>(objIn);
return outModel;
}
5. Expression表達式目錄樹轉換
/// <summary>
/// Expression表達式目錄樹轉換
/// </summary>
/// <typeparam name="TOut"></typeparam>
/// <typeparam name="TIn"></typeparam>
/// <param name="objIn"></param>
/// <returns></returns>
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 的幾個節點:
- a,b是參數,類型爲ParameterExpression
- +,*,爲二元運符,類型爲BinaryExpression
- 2爲常量,類型爲ConstantExpression
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 |