/// <summary>字典转复杂对象,反射属性赋值</summary> /// <param name="dic"></param> /// <param name="type"></param> /// <param name="target">目标对象</param> /// <returns></returns> internal Object ParseObject(IDictionary <String, Object> dic, Type type, Object target) { if (type == typeof(NameValueCollection)) { return(CreateNV(dic)); } if (type == typeof(StringDictionary)) { return(CreateSD(dic)); } if (type == typeof(Object)) { return(dic); } if (target == null) { target = type.CreateInstance(); } if (type.IsDictionary()) { return(CreateDic(dic, type, target)); } if (!_circobj.TryGetValue(target, out var circount)) { circount = _circobj.Count + 1; _circobj.Add(target, circount); _cirrev.Add(circount, target); } // 遍历所有可用于序列化的属性 var props = type.GetProperties(true).ToDictionary(e => SerialHelper.GetName(e), e => e); foreach (var item in dic) { var v = item.Value; if (v == null) { continue; } if (!props.TryGetValue(item.Key, out var pi)) { // 可能有小写 pi = props.Values.FirstOrDefault(e => e.Name.EqualIgnoreCase(item.Key)); if (pi == null) { continue; } } if (!pi.CanWrite) { continue; } var pt = pi.PropertyType; if (pt.GetTypeCode() != TypeCode.Object) { target.SetValue(pi, ChangeType(v, pt)); } else { var orig = target.GetValue(pi); var val = ToObject(v, pt, orig); if (val != orig) { target.SetValue(pi, val); } } } return(target); }
/// <summary>尝试读取</summary> /// <param name="type"></param> /// <param name="value"></param> /// <returns></returns> public override Boolean TryRead(Type type, ref Object value) { if (type == null) { if (value == null) { return(false); } type = value.GetType(); } // 不支持基本类型 if (Type.GetTypeCode(type) != TypeCode.Object) { return(false); } // 不支持基类不是Object的特殊类型 //if (type.BaseType != typeof(Object)) return false; if (!type.As <Object>()) { return(false); } var reader = Host.GetReader(); var xml = Host as Xml; // 判断类名是否一致 var name = xml.CurrentName; if (!CheckName(name, type)) { return(false); } var ms = GetMembers(type); WriteLog("XmlRead {0} 成员{1}个", type.Name, ms.Count); var dic = ms.ToDictionary(e => SerialHelper.GetName(e), e => e); if (value == null) { value = type.CreateInstance(); } Host.Hosts.Push(value); try { if (reader.NodeType == XmlNodeType.Attribute) { foreach (var item in dic) { var member = item.Value; var v = reader.GetAttribute(item.Key); WriteLog(" {0}.{1} {2}", type.Name, member.Name, v); value.SetValue(member, v); } } else { // 获取成员 var member = ms[0]; while (reader.NodeType != XmlNodeType.None && reader.IsStartElement()) { // 找到匹配的元素,否则跳过 if (!dic.TryGetValue(reader.Name, out member) || !member.CanWrite) { reader.Skip(); continue; } var mtype = GetMemberType(member); Host.Member = member; var v = value.GetValue(member); WriteLog(" {0}.{1} {2}", type.Name, member.Name, v); if (!Host.TryRead(mtype, ref v)) { return(false); } value.SetValue(member, v); } } } finally { Host.Hosts.Pop(); } return(true); }