private object DeserializeObject(Type targetType) { object result; if (targetType == typeof(string)) { result = Activator.CreateInstance(targetType, '\0', 0); } else { result = Activator.CreateInstance(targetType); } if (targetType.IsGenericType && SlimTypeInfo.DicTypes.Contains(targetType.Name)) { //dic var tinfo = SlimTypeInfo.GetOrAddInstance(targetType); result = tinfo.Instance; foreach (var item in xml.Elements()) { if (item.Attribute("item") != null) { var keyStr = item.Attribute("item").Value; var valStr = item.Value; var key = Convert.ChangeType(keyStr, tinfo.ArgTypes[0]); var val = DeserializeValue(item, tinfo.ArgTypes[1]); tinfo.MethodInfo.Invoke(result, new object[] { key, val }); } else { var key = Convert.ChangeType(item.Name.LocalName, tinfo.ArgTypes[0]); var val = DeserializeValue(item, tinfo.ArgTypes[1]); tinfo.MethodInfo.Invoke(result, new object[] { key, val }); } } } else { var dict = targetType.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => p.CanWrite) .ToDictionary(pi => pi.Name, pi => pi); foreach (var item in xml.Elements()) { PropertyInfo propertyInfo; if (!dict.TryGetValue(item.Name.LocalName, out propertyInfo)) { continue; } var value = DeserializeValue(item, propertyInfo.PropertyType); propertyInfo.SetValue(result, value, null); } } return(result); }
private object DeserializeArray(Type targetType) { if (targetType.IsArray) // Foo[] { var elemType = targetType.GetElementType(); dynamic array = Array.CreateInstance(elemType, xml.Elements().Count()); var index = 0; foreach (var item in xml.Elements()) { array[index++] = DeserializeValue(item, elemType); } return(array); } else if (targetType.IsGenericType && SlimTypeInfo.DicTypes.Contains(targetType.Name)) { //dic var tinfo = SlimTypeInfo.GetOrAddInstance(targetType); var dic = tinfo.Instance; foreach (var item in xml.Elements()) { var kv = item.Elements().ToArray(); var key = DeserializeValue(kv[0], tinfo.ArgTypes[0]); var val = DeserializeValue(kv[1], tinfo.ArgTypes[1]); tinfo.MethodInfo.Invoke(dic, new object[] { key, val }); } return(dic); } else if (targetType.IsGenericType && SlimTypeInfo.ListTypes.Contains(targetType.Name)) { //list var tinfo = SlimTypeInfo.GetOrAddInstance(targetType); var list = tinfo.Instance; foreach (var item in xml.Elements()) { var val = DeserializeValue(item, tinfo.ArgTypes[0]); tinfo.MethodInfo.Invoke(list, new object[] { val }); } return(list); } else // List<Foo> { var elemType = targetType.GetGenericArguments()[0]; dynamic list = Activator.CreateInstance(targetType); foreach (var item in xml.Elements()) { list.Add(DeserializeValue(item, elemType)); } return(list); } }
private static object DeserializeList(Type type, byte[] datas) { var info = SlimTypeInfo.GetOrAddInstance(type); var instance = info.Instance; if (info.ArgTypes[0].IsClass && info.ArgTypes[0] != typeof(string)) { //子项内容 var slen = 0; var soffset = 0; while (soffset < datas.Length) { slen = BitConverter.ToInt32(datas, soffset); if (slen > 0) { var sobj = Deserialize(info.ArgTypes[0], datas, ref soffset); if (sobj != null) { info.MethodInfo.Invoke(instance, new object[] { sobj }); } } else { info.MethodInfo.Invoke(instance, null); } } return(instance); } else { //子项内容 var slen = 0; var soffset = 0; while (soffset < datas.Length) { var len = BitConverter.ToInt32(datas, soffset); var data = new byte[len]; Buffer.BlockCopy(datas, soffset + 4, data, 0, len); soffset += 4; slen = BitConverter.ToInt32(datas, soffset); if (slen > 0) { var sobj = Deserialize(info.ArgTypes[0], datas, ref soffset); if (sobj != null) { info.MethodInfo.Invoke(instance, new object[] { sobj }); } } else { info.MethodInfo.Invoke(instance, null); } } return(instance); } }
private static object DeserializeDic(Type type, byte[] datas) { var tinfo = SlimTypeInfo.GetOrAddInstance(type); var instance = tinfo.Instance; //子项内容 var slen = 0; var soffset = 0; int m = 1; object key = null; object val = null; while (soffset < datas.Length) { slen = BitConverter.ToInt32(datas, soffset); var sdata = new byte[slen + 4]; Buffer.BlockCopy(datas, soffset, sdata, 0, slen + 4); soffset += slen + 4; if (m % 2 == 1) { object v = null; if (slen > 0) { int lloffset = 0; var sobj = Deserialize(tinfo.ArgTypes[0], sdata, ref lloffset); if (sobj != null) { v = sobj; } } key = v; } else { object v = null; if (slen > 0) { int lloffset = 0; var sobj = Deserialize(tinfo.ArgTypes[1], sdata, ref lloffset); if (sobj != null) { v = sobj; } } val = v; tinfo.MethodInfo.Invoke(instance, new object[] { key, val }); } m++; } return(instance); }
private static object DeserializeClass(Type type, byte[] datas) { var tinfo = SlimTypeInfo.GetOrAddInstance(type); var instance = tinfo.Instance; var ts = new List <Type>(); //var ps = type.GetProperties(); var fs = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); ApplyPropertySerializable(fs, type); foreach (var field in fs) { if (field != null) { ts.Add(field.FieldType); } } var vas = Deserialize(ts.ToArray(), datas); var fsWithoutNull = fs.Where(f => f != null).ToArray(); for (int j = 0; j < fsWithoutNull.Length; j++) { try { if (!fsWithoutNull[j].FieldType.IsGenericType) { fsWithoutNull[j].SetValue(instance, vas[j]); } else { Type genericTypeDefinition = fsWithoutNull[j].FieldType.GetGenericTypeDefinition(); if (genericTypeDefinition == typeof(Nullable <>)) { fsWithoutNull[j].SetValue(instance, Convert.ChangeType(vas[j], Nullable.GetUnderlyingType(fsWithoutNull[j].FieldType))); } else { fsWithoutNull[j].SetValue(instance, vas[j]); } } } catch (Exception ex) { throw new NotImplementedException("未定义的类型:" + type.ToString(), ex); } } return(instance); }
/// <summary> /// 反序列化 /// </summary> /// <param name="type"></param> /// <param name="datas"></param> /// <param name="offset"></param> /// <returns></returns> private static object Deserialize(Type type, byte[] datas, ref int offset) { dynamic obj = null; var len = 0; byte[] data = null; len = BitConverter.ToInt32(datas, offset); offset += 4; if (len > 0) { data = new byte[len]; Buffer.BlockCopy(datas, offset, data, 0, len); offset += len; if (type.IsObject()) { var lenTypeName = BitConverter.ToInt32(data, 0) + 4; byte[] dataTypeName = new byte[lenTypeName]; Buffer.BlockCopy(data, 0, dataTypeName, 0, lenTypeName); var realTypeName = (string)Deserialize(typeof(string).AssemblyQualifiedName, dataTypeName); //将获得的类型赋值后处理真正的数据 type = Type.GetType(realTypeName); var srcData = data; len = BitConverter.ToInt32(data, lenTypeName); data = new byte[len]; Buffer.BlockCopy(srcData, lenTypeName + 4, data, 0, len); } if (type == typeof(string)) { obj = Encoding.UTF8.GetString(data); } else if (type == typeof(byte)) { obj = data[0]; } else if (type == typeof(bool)) { obj = (BitConverter.ToBoolean(data, 0)); } else if (type == typeof(short)) { obj = (BitConverter.ToInt16(data, 0)); } else if (type == typeof(int)) { obj = (BitConverter.ToInt32(data, 0)); } else if (type == typeof(long)) { obj = (BitConverter.ToInt64(data, 0)); } else if (type == typeof(float)) { obj = (BitConverter.ToSingle(data, 0)); } else if (type == typeof(double)) { obj = (BitConverter.ToDouble(data, 0)); } else if (type == typeof(decimal)) { var dstr = Encoding.UTF8.GetString(data); obj = decimal.Parse(dstr);; } else if (type == typeof(DateTime)) { var dstr = Encoding.UTF8.GetString(data); var ticks = long.Parse(dstr); obj = (new DateTime(ticks)); } else if (type == typeof(Guid)) { var dstr = Encoding.UTF8.GetString(data); obj = Guid.Parse(dstr); } else if (type == typeof(Type)) { var dstr = Encoding.UTF8.GetString(data); obj = Type.GetType(dstr); } else if (type.BaseType == typeof(Enum)) { var numType = Enum.GetUnderlyingType(type); if (numType == typeof(byte)) { obj = Enum.ToObject(type, data[0]); } else if (numType == typeof(short)) { obj = Enum.ToObject(type, BitConverter.ToInt16(data, 0)); } else if (numType == typeof(int)) { obj = Enum.ToObject(type, BitConverter.ToInt32(data, 0)); } else { obj = Enum.ToObject(type, BitConverter.ToInt64(data, 0)); } } else if (type == typeof(byte[])) { obj = (byte[])data; } else if (type.IsGenericType) { if (SlimTypeInfo.ListTypes.Contains(type.Name)) { obj = DeserializeList(type, data); } else if (SlimTypeInfo.DicTypes.Contains(type.Name)) { obj = DeserializeDic(type, data); } else { obj = DeserializeClass(type, data); } } else if (type.IsArray) { obj = DeserializeArray(type, data); } else if (type.IsClass) { obj = DeserializeClass(type, data); } else { throw new NotImplementedException("未定义的类型:" + type.ToString()); } } else { var tinfo = SlimTypeInfo.GetOrAddInstance(type); obj = tinfo.Instance; } return(obj); }