public void Init(ObjectPlan plan, object value) { if (plan != null) { Plan = plan.Plan; Type = plan.Type; IsIList = plan.IsIList; IsIDictionary = plan.IsIDictionary; PlanLength = plan.Plan.Length; } SourceValue = value; _index = 0; }
private static ObjectPlan GetObjectPlan(HashSet <Type> currentObjectPlanTypes, Type type) { return(ObjectPlans.GetOrAdd(type, iType => { var typeInfo = iType.GetTypeInfo(); var genTypeDefinition = typeInfo.IsGenericType ? typeInfo.GetGenericTypeDefinition() : null; if (genTypeDefinition == typeof(Nullable <>)) { //Nullable Type iType = Nullable.GetUnderlyingType(iType); typeInfo = iType.GetTypeInfo(); } var isValue = IsValueType(iType, typeInfo); if (isValue) { var oPlan = new ObjectPlan(); var plan = new ObjectPlanItem[] { new ValuePlanItem(iType) }; oPlan.Init(plan, iType, false, false, false); return oPlan; } else { currentObjectPlanTypes.Add(iType); var ifaces = typeInfo.ImplementedInterfaces; var ifacesArray = ifaces as Type[] ?? ifaces.ToArray(); var ilist = ifacesArray.FirstOrDefault(i => i == typeof(IList) || (i.GetTypeInfo().IsGenericType&& i.GetGenericTypeDefinition() == typeof(IList <>))); var isIList = ilist != null; var idictio = ifacesArray.FirstOrDefault(i => i == typeof(IDictionary) || i.GetTypeInfo().IsGenericType&& i.GetGenericTypeDefinition() == typeof(IDictionary <,>)); var isIDictionary = idictio != null; var lPlan = new List <ObjectPlanItem>(); var tStart = new TypePlanItem(iType) { IsIList = isIList, IsIDictionary = isIDictionary }; lPlan.Add(tStart); #region Fields var fields = type.GetRuntimeFields().ToArray(); foreach (var field in fields) { if (field.IsInitOnly) { continue; } if (field.IsStatic) { continue; } if (field.IsPrivate) { continue; } if (field.IsNotSerialized) { continue; } if (field.GetAttribute <NonSerializedAttribute>() != null) { continue; } var fieldType = field.FieldType; var fieldTypeInfo = fieldType.GetTypeInfo(); var fieldIsNullable = fieldTypeInfo.IsGenericType && fieldTypeInfo.GetGenericTypeDefinition() == typeof(Nullable <>); if (fieldIsNullable) { fieldType = Nullable.GetUnderlyingType(fieldType); } var isFieldValue = IsValueType(fieldType, fieldType.GetTypeInfo()); if (isFieldValue) { lPlan.Add(new FieldValuePlanItem(field, fieldIsNullable)); } else { lPlan.Add(new FieldReferencePlanItem(field)); if (!currentObjectPlanTypes.Contains(fieldType)) { GetObjectPlan(currentObjectPlanTypes, fieldType); } } } #endregion #region Properties var properties = type.GetRuntimeProperties().ToArray(); foreach (var prop in properties) { if (!prop.CanRead || !prop.CanWrite) { continue; } if (isIList && prop.Name == "Capacity") { continue; } if (prop.GetIndexParameters().Length > 0) { continue; } var propType = prop.PropertyType; var propTypeInfo = propType.GetTypeInfo(); var propIsNullable = propTypeInfo.IsGenericType && propTypeInfo.GetGenericTypeDefinition() == typeof(Nullable <>); if (propIsNullable) { propType = Nullable.GetUnderlyingType(propType); } var isPropValue = IsValueType(propType, propType.GetTypeInfo()); if (isPropValue) { lPlan.Add(new PropertyValuePlanItem(prop, propIsNullable)); } else { lPlan.Add(new PropertyReferencePlanItem(prop)); if (!currentObjectPlanTypes.Contains(propType)) { GetObjectPlan(currentObjectPlanTypes, propType); } } } #endregion #region List if (isIList) { Type innerType = null; if (type.IsArray) { innerType = type.GetElementType(); } else { var gargs = ilist.GenericTypeArguments; if (gargs.Length == 0) { gargs = type.GenericTypeArguments; } if (gargs.Length > 0) { innerType = gargs[0]; } } var innerTypeInfo = innerType.GetTypeInfo(); var innerIsNullable = innerTypeInfo.IsGenericType && innerTypeInfo.GetGenericTypeDefinition() == typeof(Nullable <>); var innerType2 = innerType; if (innerIsNullable) { innerType2 = Nullable.GetUnderlyingType(innerType2); } var innerIsValue = IsValueType(innerType2, innerType2.GetTypeInfo()); lPlan.Add(new ListPlanItem(type, innerType, innerIsValue, innerIsNullable)); if (!currentObjectPlanTypes.Contains(innerType)) { GetObjectPlan(currentObjectPlanTypes, innerType); } } #endregion #region Dictionary if (isIDictionary) { //KeyValye Type var types = idictio.GenericTypeArguments; var keyType = types[0]; var keyTypeInfo = keyType.GetTypeInfo(); var keyIsNullable = keyTypeInfo.IsGenericType && keyTypeInfo.GetGenericTypeDefinition() == typeof(Nullable <>); var keyTypeTmp = keyType; var keyTypeInfoTmp = keyTypeInfo; if (keyIsNullable) { keyTypeTmp = Nullable.GetUnderlyingType(keyType); keyTypeInfoTmp = keyTypeTmp.GetTypeInfo(); } var keyIsValue = IsValueType(keyTypeTmp, keyTypeInfoTmp); var valueType = types[1]; var valueTypeInfo = valueType.GetTypeInfo(); var valueIsNullable = valueTypeInfo.IsGenericType && valueTypeInfo.GetGenericTypeDefinition() == typeof(Nullable <>); var valueTypeTmp = valueType; var valueTypeInfoTmp = valueTypeInfo; if (valueIsNullable) { valueTypeTmp = Nullable.GetUnderlyingType(valueTypeTmp); valueTypeInfoTmp = valueTypeTmp.GetTypeInfo(); } var valueIsValue = IsValueType(valueTypeTmp, valueTypeInfoTmp); lPlan.Add(new DictionaryPlanItem(type, keyType, keyIsValue, keyIsNullable, valueType, valueIsValue, valueIsNullable)); if (!currentObjectPlanTypes.Contains(keyType)) { GetObjectPlan(currentObjectPlanTypes, keyType); } if (!currentObjectPlanTypes.Contains(valueType)) { GetObjectPlan(currentObjectPlanTypes, valueType); } } #endregion currentObjectPlanTypes.Remove(iType); var oPlan = new ObjectPlan(); oPlan.Init(lPlan.ToArray(), iType, isIList, typeInfo.IsArray, isIDictionary); return oPlan; } })); }