|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Linq.Expressions;
|
|
|
|
|
using System.Runtime.Serialization;
|
|
|
|
|
using System.Runtime.Serialization.Formatters.Binary;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
|
|
|
|
namespace POSV.Utils
|
|
|
|
|
{
|
|
|
|
|
public static class ObjectUtils
|
|
|
|
|
{
|
|
|
|
|
//要复制的实例必须可序列化,包括实例引用的其它实例都必须在类定义时加[Serializable]特性。
|
|
|
|
|
public static T Copy<T>(T source)
|
|
|
|
|
{
|
|
|
|
|
if (!typeof(T).IsSerializable)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentException("The type must be serializable." , "source");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Don't serialize a null object, simply return the default for that object
|
|
|
|
|
if (Object.ReferenceEquals(source , null))
|
|
|
|
|
{
|
|
|
|
|
return default(T);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IFormatter formatter = new BinaryFormatter();
|
|
|
|
|
Stream stream = new MemoryStream();
|
|
|
|
|
using (stream)
|
|
|
|
|
{
|
|
|
|
|
formatter.Serialize(stream , source);
|
|
|
|
|
stream.Seek(0 , SeekOrigin.Begin);
|
|
|
|
|
return (T)formatter.Deserialize(stream);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void CopyTo(this object S , object T)
|
|
|
|
|
{
|
|
|
|
|
foreach (var pS in S.GetType().GetProperties())
|
|
|
|
|
{
|
|
|
|
|
foreach (var pT in T.GetType().GetProperties())
|
|
|
|
|
{
|
|
|
|
|
if (pT.Name != pS.Name) continue;
|
|
|
|
|
(pT.GetSetMethod()).Invoke(T , new object[]{ pS.GetGetMethod().Invoke( S, null ) });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Dictionary<string , object> _Dic = new Dictionary<string , object>();
|
|
|
|
|
|
|
|
|
|
public static TOut TransExp<TIn, TOut>(TIn tIn)
|
|
|
|
|
{
|
|
|
|
|
string key = string.Format("trans_exp_{0}_{1}" , typeof(TIn).FullName , typeof(TOut).FullName);
|
|
|
|
|
if (!_Dic.ContainsKey(key))
|
|
|
|
|
{
|
|
|
|
|
ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn) , "p");
|
|
|
|
|
List<MemberBinding> memberBindingList = new List<MemberBinding>();
|
|
|
|
|
|
|
|
|
|
foreach (var item in typeof(TOut).GetProperties())
|
|
|
|
|
{
|
|
|
|
|
MemberExpression property = Expression.Property(parameterExpression , typeof(TIn).GetProperty(item.Name));
|
|
|
|
|
MemberBinding memberBinding = Expression.Bind(item , property);
|
|
|
|
|
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();
|
|
|
|
|
_Dic[key] = func;
|
|
|
|
|
}
|
|
|
|
|
return ((Func<TIn , TOut>)_Dic[key])(tIn);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static T CloneJson<T>(this T source)
|
|
|
|
|
{
|
|
|
|
|
// Don't serialize a null object, simply return the default for that object
|
|
|
|
|
if (Object.ReferenceEquals(source , null))
|
|
|
|
|
{
|
|
|
|
|
return default(T);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// initialize inner objects individually
|
|
|
|
|
// for example in default constructor some list property initialized with some values,
|
|
|
|
|
// but in 'source' these items are cleaned -
|
|
|
|
|
// without ObjectCreationHandling.Replace default constructor values will be added to result
|
|
|
|
|
var deserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace };
|
|
|
|
|
|
|
|
|
|
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source) , deserializeSettings);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static class TransExpV2<TIn, TOut>
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
private static readonly Func<TIn , TOut> cache = GetFunc();
|
|
|
|
|
private static Func<TIn , TOut> GetFunc()
|
|
|
|
|
{
|
|
|
|
|
ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn) , "p");
|
|
|
|
|
List<MemberBinding> memberBindingList = new List<MemberBinding>();
|
|
|
|
|
|
|
|
|
|
foreach (var item in typeof(TOut).GetProperties())
|
|
|
|
|
{
|
|
|
|
|
if (!item.CanWrite)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
MemberExpression property = Expression.Property(parameterExpression , typeof(TIn).GetProperty(item.Name));
|
|
|
|
|
MemberBinding memberBinding = Expression.Bind(item , property);
|
|
|
|
|
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 });
|
|
|
|
|
|
|
|
|
|
return lambda.Compile();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static TOut Trans(TIn tIn)
|
|
|
|
|
{
|
|
|
|
|
return cache(tIn);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|