public void WritePropertyValue(BinPropertyReflection prop, object instance, BinaryWriter writer)
        {
            object value = prop.Property.GetValue(instance);

            if (prop.SerializeCast != null)
            {
                value = prop.SerializeCast(value);
            }


            WritePropertyValue(value, prop.PhoenixValueType, writer);
        }
        public void WritePropertyName(BinPropertyReflection prop, BinaryWriter writer)
        {
            int key;

            if (!_stringTable.TryGetValue(prop.SerializeName, out key))
            {
                key = _stringTable.Count;
                _stringTable.Add(prop.SerializeName, key);
            }

            writer.Write((byte)PhoenixTypeCode.StringRef);
            //if (key == 0x1a)
            //{

            //}
            writer.Write((Int32)key);
        }
        public List <BinPropertyReflection> ReflectProperties(Type baseType)
        {
            if (_cache.TryGetValue(baseType, out List <BinPropertyReflection> c))
            {
                return(c);
            }

            List <BinPropertyReflection> result = new List <BinPropertyReflection>();

            var propertys = baseType.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
            // Dictionary<string, System.Reflection.PropertyInfo> _name2Prop = new Dictionary<string, System.Reflection.PropertyInfo>();

            int  i        = 0;
            bool reorderd = false;

            foreach (var prop in propertys)
            {
                // Check Ignore
                var attributes = prop.GetCustomAttributes(typeof(JsonIgnoreAttribute), false);
                if (attributes != null & attributes.Length > 0)
                {
                    continue;
                }

                BinPropertyReflection reflection = new BinPropertyReflection()
                {
                    Index    = i++,
                    Property = prop
                };


                // Check Rename and Sorting
                attributes = prop.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
                if (attributes != null & attributes.Length > 0)
                {
                    var attribut = (attributes[0] as JsonPropertyAttribute);
                    if (attribut.PropertyName != null)
                    {
                        reflection.SerializeName = attribut.PropertyName;
                    }
                    else
                    {
                        reflection.SerializeName = prop.Name;
                    }

                    if (attribut.Order != 0)
                    {
                        reflection.Index = attribut.Order;
                        reorderd         = true;
                    }
                }
                else
                {
                    reflection.SerializeName = prop.Name;
                }


                attributes = prop.GetCustomAttributes(typeof(PhoenixBinTypeAttribute), false);
                if (attributes != null & attributes.Length > 0)
                {
                    var attribut = (attributes[0] as PhoenixBinTypeAttribute);
                    reflection.PhoenixValueType = attribut.PhoenixType;

                    switch (attribut.DeserializeConverter)
                    {
                    case BinPropertyReflection.DeserializeConverter.FloatDoubleTransform:
                        reflection.DeserializeCast = BinPropertyReflection.FloatDoubleTransform;
                        break;

                    default:
                        break;
                    }

                    if (attribut.PhoenixType == PhoenixTypeCode.Float)
                    {
                        reflection.DeserializeCast = BinPropertyReflection.FloatDoubleTransform;
                        reflection.SerializeCast   = BinPropertyReflection.DoubleFloatTransform;
                    }

                    switch (attribut.SerilizeConverter)
                    {
                    case BinPropertyReflection.SerializeConverter.TickToLong:
                        reflection.SerializeCast = BinPropertyReflection.TickToLong;
                        break;

                    default:
                        break;
                    }
                }
                else
                {
                    reflection.PhoenixValueType = GetPhoenixTypeCode(prop.PropertyType);
                }

                attributes = prop.GetCustomAttributes(typeof(CombinedNullIgnoreAttribute), false);
                if (attributes != null & attributes.Length > 0)
                {
                    reflection.CombinedNullIgnore = true;
                }

                result.Add(reflection);
            }

            if (reorderd)
            {
                result = result.OrderBy(x => x.Index).ToList();
            }

            _cache.Add(baseType, result);

            return(result);
        }