Ejemplo n.º 1
0
 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;
 }
Ejemplo n.º 2
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;
                }
            }));
        }