您如何使用hashset 与c#中的二进制读取器一起使用

问题描述 投票:0回答:1

我正在尝试将hashset<string>保存到数据库中然后检索它,但是我不知道如何为此使用二进制读取器。

#region Types中的位置

TypeList = new Dictionary<string, Type>

我有:

[typeof(HashSet<string>).FullName]=typeof(HashSet<string>)

要写,我有:

[typeof(HashSet<string>)] = (v,w) =>
            {
                w.Write(v != null);
                if (v == null) return;
                HashSet<string> datas = (HashSet<string>)v;
                w.Write(datas.Count);
                foreach(string data in datas)
                {
                    w.Write(data);
                }
            }

但是我不知道如何将其从数据库读回哈希集

            [typeof(HashSet<string>)] = r=>
            {
                int length = r.ReadInt32();
                HashSet<string> data = new HashSet<string>();
                for (int i = 0; i < length; i++)
                    data.Add(r.ReadString());

                return data;
            }

此操作失败并显示错误:

无法读取到流的末尾。

我对二进制阅读器的了解非常低,我不确定如何从数据库中读取哈希集。显然,该循环不会完全正确,因为哈希集中没有length(),没有对值进行索引等,其优点(以及为什么我需要在代码的其他地方使用它)是,它永远不能包含两个相同的值。

r.count不起作用(即使那是您如何找到哈希集的“长度”,我也不知道如何对r内的值进行迭代(即使那是您的方式),这驱使我现在在墙上呆了两天。

澄清:我正在添加一个开放源代码游戏,用户数据存储在数据库中,我的哈希集数组未保存时出现问题,似乎处理数据库的类需要定义的每种类型,对我来说很陌生的区域之前从未真正处理过数据存储。我向我保证,一旦添加了定义以告诉它如何处理哈希集,那么哈希集将保存...。但是我不知道该怎么做,我正在尝试并且已经存在了一段时间(并且仍然是)。具有讽刺意味的是,这是我正在努力保持精神和心理健康同时被屏蔽的工作,后者肯定正在遭受痛苦

全班:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Library;

namespace MirDB
{
public sealed class DBValue
{
    internal static readonly Dictionary<string, Type> TypeList;
    private static readonly Dictionary<Type, Func<BinaryReader, object>> TypeRead;
    private static readonly Dictionary<Type, Action<object, BinaryWriter>> TypeWrite;

    static DBValue()
    {
        #region Types
        TypeList = new Dictionary<string, Type>
        {
            [typeof(Boolean).FullName] = typeof(Boolean),
            [typeof(Byte).FullName] = typeof(Byte),
            [typeof(Byte[]).FullName] = typeof(Byte[]),
            [typeof(Char).FullName] = typeof(Char),
            [typeof(Color).FullName] = typeof(Color),
            [typeof(DateTime).FullName] = typeof(DateTime),
            [typeof(Decimal).FullName] = typeof(Decimal),
            [typeof(Double).FullName] = typeof(Double),
            [typeof(Int16).FullName] = typeof(Int16),
            [typeof(Int32).FullName] = typeof(Int32),
            [typeof(Int32[]).FullName] = typeof(Int32[]),
            [typeof(Int64).FullName] = typeof(Int64),
            [typeof(Point).FullName] = typeof(Point),
            [typeof(SByte).FullName] = typeof(SByte),
            [typeof(Single).FullName] = typeof(Single),
            [typeof(Size).FullName] = typeof(Size),
            [typeof(String).FullName] = typeof(String),
            [typeof(TimeSpan).FullName] = typeof(TimeSpan),
            [typeof(UInt16).FullName] = typeof(UInt16),
            [typeof(UInt32).FullName] = typeof(UInt32),
            [typeof(UInt64).FullName] = typeof(UInt64),
            [typeof(Point[]).FullName] = typeof(Point[]),
            [typeof(Stats).FullName] = typeof(Stats),
            [typeof(BitArray).FullName] = typeof(BitArray),
            [typeof(HashSet<string>).FullName]=typeof(HashSet<string>)
        };
        #endregion

        #region Reads

        TypeRead = new Dictionary<Type, Func<BinaryReader, object>>
        {
            [typeof(Boolean)] = r => r.ReadBoolean(),
            [typeof(Byte)] = r => r.ReadByte(),
            [typeof(Byte[])] = r => r.ReadBytes(r.ReadInt32()),
            [typeof(Char)] = r => r.ReadChar(),
            [typeof(Color)] = r => Color.FromArgb(r.ReadInt32()),
            [typeof(DateTime)] = r => DateTime.FromBinary(r.ReadInt64()),
            [typeof(Decimal)] = r => r.ReadDecimal(),
            [typeof(Double)] = r => r.ReadDouble(),
            [typeof(Enum)] = r => r.ReadInt32(),
            [typeof(Int16)] = r => r.ReadInt16(),
            [typeof(Int32)] = r => r.ReadInt32(),
            [typeof(Int32[])] = r =>
            {
                if (!r.ReadBoolean()) return null;

                int length = r.ReadInt32();

                Int32[] values = new Int32[length];
                for (int i = 0; i < length; i++)
                    values[i] = r.ReadInt32();

                return values;

            },
            [typeof(Int64)] = r => r.ReadInt64(),
            [typeof(Point)] = r => new Point(r.ReadInt32(), r.ReadInt32()),
            [typeof(SByte)] = r => r.ReadSByte(),
            [typeof(Single)] = r => r.ReadSingle(),
            [typeof(Size)] = r => new Size(r.ReadInt32(), r.ReadInt32()),
            [typeof(String)] = r => r.ReadString(),
            [typeof(TimeSpan)] = r => TimeSpan.FromTicks(r.ReadInt64()),
            [typeof(UInt16)] = r => r.ReadUInt16(),
            [typeof(UInt32)] = r => r.ReadUInt32(),
            [typeof(UInt64)] = r => r.ReadUInt64(),
            [typeof(Point[])] = r =>
            {
                if (!r.ReadBoolean()) return null;

                int length = r.ReadInt32();

                Point[] points = new Point[length];
                for (int i = 0; i < length; i++)
                    points[i] = new Point(r.ReadInt32(), r.ReadInt32());

                return points;

            },
            [typeof(Stats)] = r => r.ReadBoolean() ? new Stats(r) : null,
            [typeof(BitArray)] = r =>
            {
                if (!r.ReadBoolean()) return null;

                return new BitArray(r.ReadBytes(r.ReadInt32()));
            },
            [typeof(HashSet<string>)] = r=>
            {
                int length =r.ReadInt32();
                string[] temp = new string[length];


                for (int i = 0; i < length; i++)
                {
                    temp[i] = r.ReadString();
                }
                HashSet<string> data = new HashSet<string>();
                foreach(string indata in temp)
                {
                    data.Add(indata);
                }
                return data;               
            }
        };

        #endregion

        #region Writes

        TypeWrite = new Dictionary<Type, Action<object, BinaryWriter>>
        {
            [typeof(Boolean)] = (v, w) => w.Write((bool) v),
            [typeof(Byte)] = (v, w) => w.Write((Byte) v),
            [typeof(Byte[])] = (v, w) =>
            {
                w.Write(((Byte[]) v).Length);
                w.Write((Byte[]) v);
            },
            [typeof(Char)] = (v, w) => w.Write((Char) v),
            [typeof(Color)] = (v, w) => w.Write(((Color) v).ToArgb()),
            [typeof(DateTime)] = (v, w) => w.Write(((DateTime) v).ToBinary()),
            [typeof(Decimal)] = (v, w) => w.Write((Decimal) v),
            [typeof(Double)] = (v, w) => w.Write((Double) v),
            [typeof(Int16)] = (v, w) => w.Write((Int16) v),
            [typeof(Int32)] = (v, w) => w.Write((Int32) v),
            [typeof(Int32[])] = (v, w) =>
            {
                w.Write(v != null);
                if (v == null) return;
                Int32[] values = (Int32[]) v;

                w.Write(values.Length);

                foreach (Int32 value in values)
                    w.Write(value);
            },
            [typeof(Int64)] = (v, w) => w.Write((Int64) v),
            [typeof(Point)] = (v, w) =>
            {
                w.Write(((Point) v).X);
                w.Write(((Point) v).Y);
            },
            [typeof(SByte)] = (v, w) => w.Write((SByte) v),
            [typeof(Single)] = (v, w) => w.Write((Single) v),
            [typeof(Size)] = (v, w) =>
            {
                w.Write(((Size) v).Width);
                w.Write(((Size) v).Height);
            },
            [typeof(String)] = (v, w) => w.Write((String) v ?? string.Empty),
            [typeof(TimeSpan)] = (v, w) => w.Write(((TimeSpan) v).Ticks),
            [typeof(UInt16)] = (v, w) => w.Write((UInt16) v),
            [typeof(UInt32)] = (v, w) => w.Write((UInt32) v),
            [typeof(UInt64)] = (v, w) => w.Write((UInt64) v),
            [typeof(Point[])] = (v, w) =>
            {
                w.Write(v != null);
                if (v == null) return;
                Point[] points = (Point[]) v;

                w.Write(points.Length);

                foreach (Point point in points)
                {
                    w.Write(point.X);
                    w.Write(point.Y);
                }
            },
            [typeof(Stats)] = (v, w) =>
            {
                w.Write(v != null);
                if (v == null) return;

                ((Stats)v).Write(w);
            },
            [typeof(BitArray)] = (v, w) =>
            {
                w.Write(v != null);
                if (v == null) return;

                BitArray array = (BitArray) v;


                byte[] bytes = new byte[(int) Math.Ceiling(array.Length/8d)];
                array.CopyTo(bytes, 0);

                w.Write(bytes.Length);
                w.Write(bytes);
            },
            [typeof(HashSet<string>)] = (v,w) =>
            {
                w.Write(v != null);
                if (v == null) return;
                HashSet<string> datas = (HashSet<string>)v;
                w.Write(datas.Count);
                foreach(string data in datas)
                {
                    w.Write(data);
                }
            }
        };

        #endregion
    }

    public string PropertyName { get; }
    public Type PropertyType { get; }
    public PropertyInfo Property { get; }

    public DBValue(BinaryReader reader, Type type)
    {
        PropertyName = reader.ReadString();
        PropertyType = TypeList[reader.ReadString()];


        PropertyInfo property = type?.GetProperty(PropertyName);

        if (property != null)
            if (property.GetCustomAttribute<IgnoreProperty>() != null) 
return;

        Property = property;
    }
    public DBValue(PropertyInfo property)
    {
        Property = property;

        PropertyName = property.Name;

        if (property.PropertyType.IsEnum)
        {
            PropertyType = property.PropertyType.GetEnumUnderlyingType();
            return;
        }

        if (property.PropertyType.IsSubclassOf(typeof(DBObject)))
        {
            PropertyType = typeof(int);
            return;
        }

        PropertyType = property.PropertyType;
    }

    public void Save(BinaryWriter writer)
    {
        writer.Write(PropertyName);
        writer.Write(PropertyType.FullName);
    }

    public object ReadValue(BinaryReader reader)
    {
        return TypeRead[PropertyType](reader);
    }
    public void WriteValue(object value, BinaryWriter writer)
    {
        TypeWrite[PropertyType](value, writer);
    }


    public bool IsMatch(DBValue value)
    {
        return string.Compare(PropertyName, value.PropertyName, StringComparison.Ordinal) == 0 && PropertyType == value.PropertyType;
    }
}

}

我正在尝试将哈希集保存到数据库,然后检索它,但是我不知道如何为此使用二进制读取器。在#region类型TypeType =新字典中[<...>

c# hashset binaryreader
1个回答
0
投票

似乎我一开始不是在阅读布尔值。...这条线使我绕弯转了两天.....简直看不到它丢失了。

© www.soinside.com 2019 - 2024. All rights reserved.