Пример #1
0
 public void Clear()
 {
     Properties           = null;
     PropertiesLength     = 0;
     CurrentPropertyIndex = 0;
     Operation            = 0;
     Value           = null;
     ListValue       = null;
     DictionaryValue = null;
     Type            = null;
     TypeInfo        = null;
     ListIndex       = 0;
 }
Пример #2
0
        public void SetProperties(Type type, string[] properties, Dictionary <Type, Type[]> propertiesTypes, int length)
        {
            Type        = type;
            TypeInfo    = GetDeserializationTypeInfo(type);
            CurrentType = type;
            if (properties.Length == 0 && length == -1)
            {
                Value = null;
            }
            else
            {
                Value = TypeInfo.CreateInstance(length);
            }

            if (TypeInfo.IsIList)
            {
                ListValue = (IList)Value;
            }
            else if (TypeInfo.IsIDictionary)
            {
                DictionaryValue = (IDictionary)Value;
            }

            if (properties.Length <= 0)
            {
                return;
            }

            Properties       = properties;
            PropertiesLength = properties.Length;
            if (!propertiesTypes.TryGetValue(type, out PropertiesType))
            {
                PropertiesType = new Type[properties.Length];
                for (var i = 0; i < properties.Length; i++)
                {
                    PropertiesType[i] = TypeInfo.Properties[properties[i]].Property.PropertyType;
                }
                propertiesTypes[type] = PropertiesType;
            }
            CurrentType          = PropertiesType[0];
            CurrentPropertyIndex = 0;
            Operation            = 0;
        }
Пример #3
0
        private static DeserializerTypeInfo GetDeserializationTypeInfo(Type type)
        {
            if (type is null)
            {
                return(null);
            }
            return(DeserializationTypeInfo.GetOrAdd(type, valueType =>
            {
                if (valueType is null)
                {
                    return null;
                }
                var typeInfo = valueType.GetTypeInfo();
                var isGenericType = typeInfo.IsGenericType;

                var tinfo = new DeserializerTypeInfo
                {
                    Type = valueType,
                    Properties = valueType.GetRuntimeProperties().Where(p =>
                    {
                        var ok = !p.IsSpecialName && p.CanRead && p.CanWrite;
                        if (!ok)
                        {
                            return false;
                        }
                        return p.GetIndexParameters().Length <= 0;
                    }).Select(p => new DeserializerTypeInfo.FPropertyInfo
                    {
                        Property = p.GetFastPropertyInfo(),
                        IsEnum = p.PropertyType.IsEnum,
                        UnderlyingType = p.PropertyType.GetUnderlyingType()
                    }).ToDictionary(k => k.Property.Name, v => v)
                };
                var constructor = typeInfo.DeclaredConstructors.FirstOrDefault(c => c.GetParameters().Length == 0) ??
                                  typeInfo.DeclaredConstructors.First();
                tinfo.Activator = Factory.Accessors.CreateActivator(constructor);
                tinfo.ActivatorParametersTypes = constructor.GetParameters().Select(p => p.ParameterType).ToArray();
                tinfo.IsArray = valueType.IsArray;

                //
                var ifaces = typeInfo.ImplementedInterfaces.ToArray();


                var ilist = ifaces.FirstOrDefault(i => i == typeof(IList) || (i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList <>)));
                if (ilist != null)
                {
                    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];
                        }
                        else
                        {
                            var iListType = typeInfo.ImplementedInterfaces.FirstOrDefault(m => (m.IsGenericType && m.GetGenericTypeDefinition() == typeof(IList <>)));
                            if (iListType != null && iListType.GenericTypeArguments.Length > 0)
                            {
                                innerType = iListType.GenericTypeArguments[0];
                            }
                        }
                    }
                    tinfo.IsIList = true;
                    tinfo.InnerTypes = new[] { innerType };
                }

                var idictio = ifaces.FirstOrDefault(i => i == typeof(IDictionary) || (i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary <,>)));
                if (idictio != null)
                {
                    tinfo.IsIDictionary = true;
                    tinfo.InnerTypes = idictio.GenericTypeArguments;
                }

                if (!tinfo.IsIList && !tinfo.IsIDictionary && isGenericType)
                {
                    tinfo.InnerTypes = typeInfo.GenericTypeArguments;
                }

                if (tinfo.IsIList && type.GenericTypeArguments.Length == 1 && type.GetGenericTypeDefinition() == typeof(List <>))
                {
                    tinfo.IsTypeList = true;
                }
                else if (tinfo.IsIDictionary && type.GenericTypeArguments.Length == 2 && type.GetGenericTypeDefinition() == typeof(Dictionary <,>))
                {
                    tinfo.IsTypeDictionary = true;
                }

                return tinfo;
            }));
        }