将充满位和字节的ushort []反序列化为自定义对象

问题描述

我有一个包含450个成员的ushort [],它重复了12个bool和1个字节的值,如下所示:

我需要从数组中获取Person对象,或者从ushort[]获取List<Person>,所以基本上我需要对该ushort[]进行反序列化和序列化。

要轻松解析它,我想也许可以将它反序列化为单个对象,但是在看起来很糟糕之后就放弃了:

class Person
{
    public bool Property0 { get; set; }
    public bool Property1 { get; set; }
    public bool Property2 { get; set; }
    public bool Property3 { get; set; }
    public bool Property4 { get; set; }
    public bool Property5 { get; set; }
    public bool Property6 { get; set; }
    public bool Property7 { get; set; }
    public bool Property8 { get; set; }
    public bool Property9 { get; set; }
    public bool Property10 { get; set; }
    public bool Property11 { get; set; }
    public byte Property12 { get; set; }
}


private List<Person> Deserialize(ushort[] array)
{
    var personList = new List<Person>();
    Person person1 = new Person();
    Person person2 = new Person();
    for (int i = 0; i < array.Length; i++)
    {
        BitArray bitArray = new BitArray(array[i]);

        if (i % 3 == 0)
        {
            person1 = new Person();
            person1.Property0 = bitArray[0];
            person1.Property1 = bitArray[1];
            person1.Property2 = bitArray[2];
            person1.Property3 = bitArray[3];
            person1.Property4 = bitArray[4];
            person1.Property5 = bitArray[5];
            person1.Property6 = bitArray[6];
            person1.Property7 = bitArray[7];
            person1.Property8 = bitArray[8];
            person1.Property9 = bitArray[9];
            person1.Property10 = bitArray[10];
            person1.Property11 = bitArray[11];
        }

        if (i % 3 == 1)
        {
            byte[] bytes = new byte[1];
            bitArray.copyTo(bytes,0);
            person1.Property12 = bytes[0];
            
            personList.Add(person1);

            person2 = new Person();
            person2.Property0 = bitArray[0];
            person2.Property1 = bitArray[1];
            person2.Property2 = bitArray[2];
            person2.Property3 = bitArray[3];
            person2.Property4 = bitArray[4];
            person2.Property5 = bitArray[5];
            person2.Property6 = bitArray[6];
            person2.Property7 = bitArray[7];
        }

        if (i % 3 == 2)
        {
            person2.Property8 = bitArray[8];
            person2.Property9 = bitArray[9];
            person2.Property10 = bitArray[10];
            person2.Property11 = bitArray[11];

            byte[] bytes = new byte[1];
            bitArray.copyTo(bytes,5);
            person2.Property12 = bytes[0];

            personList.Add(person2);
        }
    }
    return personList;
}

如何使它漂亮?

我使用属性对json进行序列化/反序列化,但是库可以完成工作,数组反序列化有类似的东西吗?

谢谢。

解决方法

如果必须进行反序列化,我将采用以下方法作为开始并对其进行改进。

首先,我将Person类更新为:

public class Person
{
    private readonly BitArray booleanPropertyBits;
    private readonly byte bit16To23;
    
    public Person(byte byte1,byte byte2,byte byte3)
    {
        booleanPropertyBits = new BitArray(new byte[] { byte1,byte2 });
        bit16To23 = byte3;
    }

    public bool Property0 => booleanPropertyBits[0];
    public bool Property1 => booleanPropertyBits[1];
    public bool Property2 => booleanPropertyBits[2];
    public bool Property3 => booleanPropertyBits[3];
    public bool Property4 => booleanPropertyBits[4];
    public bool Property5 => booleanPropertyBits[5];
    public bool Property6 => booleanPropertyBits[6];
    public bool Property7 => booleanPropertyBits[7];
    public bool Property8 => booleanPropertyBits[8];
    public bool Property9 => booleanPropertyBits[9];
    public bool Property10 => booleanPropertyBits[10];
    public bool Property11 => booleanPropertyBits[11];
    public byte Property12 => bit16To23;
}

在那之后,我将创建一个帮助程序类,该类会将ushort []转换为byte [],例如:

public static class ByteStream
{
    public static IEnumerable<byte> From(ushort[] array)
    {
        foreach (var number in array)
        {
            var bytes = BitConverter.GetBytes(number);
            foreach (var b in bytes)
            {
                yield return b;
            }
        }
    }
}

最后,我将使用辅助方法以以下方式读取值:

private List<Person> Deserialize(ushort[] array)
{
    var bytes = ByteStream.From(array).ToArray();
    var retVal = new List<Person>();

    for (int i = 0; i < bytes.Length; i += 3)
    {
        var person = new Person(bytes[i],bytes[i + 1],bytes[i + 2]);
        retVal.Add(person);
    }

    return retVal;
}

这不是一个完整的解决方案,但是可以通过添加验证检查和一些性能调整来开始和改进。