private DateTimeOffset ReadDateTimeOffset(BinaryReader reader)
        {
            var offsetMinutes = PrimitivesConvertion.ReadVarInt16(reader);

            var ticks = PrimitivesConvertion.ReadVarInt64(reader);

            return(new DateTimeOffset(ticks, TimeSpan.FromMinutes(offsetMinutes)));
        }
        private object ReadMember(BinaryReader reader, MemberInfo memInfo, Type memType)
        {
            if ((memInfo.IsNullable && memInfo.IsContainerObject) ||
                (memInfo.IsNullable && !memInfo.IsSupportedPrimitive && (!memInfo.IsContainerObject || memInfo.IsStruct)))
            {
                bool isNull = reader.ReadByte() != 0;

                if (isNull)
                {
                    return(null);
                }
            }
            var actualMemberType = memType;

            if (memInfo.IsNullable && memInfo.NullableUnderlyingType != null)
            {
                actualMemberType = memInfo.NullableUnderlyingType;
            }

            switch (memInfo.KnownType)
            {
            case EnKnownType.Unknown:

                if (memInfo.IsContainerObject)
                {
                    return(ReadObject(reader, actualMemberType));
                }
                else if (memInfo.IsStringDictionary)
                {
                    return(ReadStringDictionary(reader, actualMemberType));
                }
                else if (memInfo.IsDictionary)
                {
                    return(ReadDictionary(reader, actualMemberType));
                }
                else if (memInfo.IsCollection)
                {
                    if (memInfo.IsGeneric)
                    {
                        return(ReadGenericList(reader, actualMemberType));
                    }
                    return(ReadArray(reader, actualMemberType));
                }
                else if (memInfo.IsArray)
                {
                    return(ReadArray(reader, actualMemberType));
                }

                break;

            case EnKnownType.Int16:
                if (memInfo.IsNullable)
                {
                    return(PrimitivesConvertion.ReadVarInt16Nullable(reader));
                }
                return(PrimitivesConvertion.ReadVarInt16(reader));

            case EnKnownType.UInt16:
                if (memInfo.IsNullable)
                {
                    return(PrimitivesConvertion.ReadVarUInt16Nullable(reader));
                }
                return(PrimitivesConvertion.ReadVarUInt16(reader));

            case EnKnownType.Int32:
                if (memInfo.IsNullable)
                {
                    return(PrimitivesConvertion.ReadVarInt32Nullable(reader));
                }
                return(PrimitivesConvertion.ReadVarInt32(reader));

            case EnKnownType.Int64:
                if (memInfo.IsNullable)
                {
                    return(PrimitivesConvertion.ReadVarInt64Nullable(reader));
                }
                return(PrimitivesConvertion.ReadVarInt64(reader));

            case EnKnownType.UInt64:
                if (memInfo.IsNullable)
                {
                    return(PrimitivesConvertion.ReadVarUInt64Nullable(reader));
                }
                return(PrimitivesConvertion.ReadVarUInt64(reader));

            case EnKnownType.UInt32:
                if (memInfo.IsNullable)
                {
                    return(PrimitivesConvertion.ReadVarUInt32Nullable(reader));
                }
                return(PrimitivesConvertion.ReadVarUInt32(reader));

            case EnKnownType.Double:
                if (memInfo.IsNullable)
                {
                    return(PrimitivesConvertion.ReadVarDoubleNullable(reader));
                }
                return(PrimitivesConvertion.ReadVarDouble(reader));

            case EnKnownType.Decimal:
                if (memInfo.IsNullable)
                {
                    return(PrimitivesConvertion.ReadVarDecimalNullable(reader));
                }
                return(PrimitivesConvertion.ReadVarDecimal(reader));

            case EnKnownType.Single:
                if (memInfo.IsNullable)
                {
                    return(PrimitivesConvertion.ReadVarSingleNullable(reader));
                }
                return(PrimitivesConvertion.ReadVarSingle(reader));

            case EnKnownType.Byte:
                return(reader.ReadByte());

            case EnKnownType.SByte:
                return(reader.ReadSByte());

            case EnKnownType.ByteArray:
                return(ReadBytes(reader));

            case EnKnownType.String:
                return(ReadString(reader));

            case EnKnownType.Char:
                var charByte = reader.ReadUInt16();
                return((char)charByte);

            case EnKnownType.Bool:
                return(ReadBoolean(reader));

            case EnKnownType.Enum:
                return(ReadEnum(reader, actualMemberType));

            case EnKnownType.DateTime:
                return(ReadDateTime(reader));

            case EnKnownType.DateTimeOffset:
                return(ReadDateTimeOffset(reader));

            case EnKnownType.TimeSpan:
                return(ReadTimeSpan(reader));

            case EnKnownType.DataSet:
                return(ReadDataset(reader, actualMemberType));

            case EnKnownType.DataTable:
                return(ReadDataTable(reader));

            case EnKnownType.NameValueColl:
                return(ReadCollectionNameValue(reader, actualMemberType));

            case EnKnownType.Color:
                return(ReadColor(reader));

            case EnKnownType.Version:
                return(ReadVersion(reader));

            case EnKnownType.DbNull:
                return(DBNull.Value);

            case EnKnownType.Guid:
                return(ReadGuid(reader));

            case EnKnownType.Uri:
                return(ReadUri(reader));

            default:
                throw new ArgumentOutOfRangeException();
            }
            return(null);
        }