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 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 _Dic = new Dictionary(); public static TOut TransExp(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 memberBindingList = new List(); 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> lambda = Expression.Lambda>(memberInitExpression , new ParameterExpression[] { parameterExpression }); Func func = lambda.Compile(); _Dic[key] = func; } return ((Func)_Dic[key])(tIn); } public static T CloneJson(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(JsonConvert.SerializeObject(source) , deserializeSettings); } } public static class TransExpV2 { private static readonly Func cache = GetFunc(); private static Func GetFunc() { ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn) , "p"); List memberBindingList = new List(); 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> lambda = Expression.Lambda>(memberInitExpression , new ParameterExpression[] { parameterExpression }); return lambda.Compile(); } public static TOut Trans(TIn tIn) { return cache(tIn); } } }