private static bool TryRecursive(Type type, out ReadValueDelegate readValue, out WriteValueDelegate writeValue)
        {
            var cache = BinarySerializerCache.InternalRegisterTypes(type);

            if (cache == null)
            {
                foreach (var typeConverter in BinarySerializerCache.TypeConverterCache.Values)
                {
                    if (typeConverter.CanConvertTo(typeof(byte[])) && typeConverter.CanConvertFrom(type))
                    {
                        readValue = (deserializer, reader) =>
                        {
                            var buffer = ReadVarBytes(reader, 100);
                            return(typeConverter.ConvertFrom(null, CultureInfo.InvariantCulture, buffer));
                        };
                        writeValue = (serializer, writer, value) =>
                        {
                            var buffer = (byte[])typeConverter.ConvertTo(value, typeof(byte[]));
                            return(WriteVarBytes(writer, buffer));
                        };
                        return(true);
                    }
                }

                readValue  = null;
                writeValue = null;
                return(false);
            }

            var r = new RecursiveType(type);

            readValue  = r.GetRecursiveValue;
            writeValue = r.SetRecursiveValue;
            return(true);
        }
 public ArrayType(Type type, int maxLength, ReadValueDelegate get, WriteValueDelegate set)
 {
     MaxLength = maxLength;
     GetValue  = get;
     SetValue  = set;
     Type      = type;
 }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="atr">Attribute</param>
        /// <param name="btype">Type</param>
        private BinarySerializerCacheEntry(BinaryPropertyAttribute atr, Type btype)
        {
            var type    = btype;
            var isArray = type.IsArray;
            var isList  = _iListType.IsAssignableFrom(type);

            MaxLength = atr == null ? 0 : atr.MaxLength;

            if (type == typeof(byte[]))
            {
                ReadValue  = GetByteArrayValue;
                WriteValue = SetByteArrayValue;
            }
            else
            {
                if (isArray || isList)
                {
                    // Extract type of array
                    type = type.GetElementType();
                }

                if (type.IsEnum)
                {
                    type = Enum.GetUnderlyingType(type);
                }

                if (type == typeof(string))
                {
                    ReadValue  = GetStringValue;
                    WriteValue = SetStringValue;
                }
                else if (type == typeof(long))
                {
                    ReadValue  = GetInt64Value;
                    WriteValue = SetInt64Value;
                }
                else if (type == typeof(ulong))
                {
                    ReadValue  = GetUInt64Value;
                    WriteValue = SetUInt64Value;
                }
                else if (type == typeof(int))
                {
                    ReadValue  = GetInt32Value;
                    WriteValue = SetInt32Value;
                }
                else if (type == typeof(uint))
                {
                    ReadValue  = GetUInt32Value;
                    WriteValue = SetUInt32Value;
                }
                else if (type == typeof(short))
                {
                    ReadValue  = GetInt16Value;
                    WriteValue = SetInt16Value;
                }
                else if (type == typeof(ushort))
                {
                    ReadValue  = GetUInt16Value;
                    WriteValue = SetUInt16Value;
                }
                else if (type == typeof(byte))
                {
                    ReadValue  = GetByteValue;
                    WriteValue = SetByteValue;
                }
                else if (type == typeof(sbyte))
                {
                    ReadValue  = GetSByteValue;
                    WriteValue = SetSByteValue;
                }
                else if (type == typeof(bool))
                {
                    ReadValue  = GetBoolValue;
                    WriteValue = SetBoolValue;
                }
                else if (type == typeof(double))
                {
                    ReadValue  = GetDoubleValue;
                    WriteValue = SetDoubleValue;
                }
                else if (!TryRecursive(type, out ReadValue, out WriteValue))
                {
                    throw new NotImplementedException();
                }

                if (isArray)
                {
                    var ar = new ArrayType(btype, MaxLength, ReadValue, WriteValue);
                    ReadValue  = ar.GetArrayValue;
                    WriteValue = ar.SetArrayValue;
                }
                else if (isList)
                {
                    var ls = new ListType(btype, MaxLength, ReadValue, WriteValue);
                    ReadValue  = ls.GetListValue;
                    WriteValue = ls.SetListValue;
                }
            }
        }