在不知道类型的情况下循环遍历 List<> 中的项目?

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

我正在尝试为我的类编写一个序列化器,以便任何属性都映射到字节编写器。我需要循环遍历实际列表中每个项目的

List<>
属性,现在
WriteCollectionPropertyToWriter
只需写入一次。

我怎样才能让这个方法(

WriteCollectionPropertyToWriter
)基本上对每个项目递归地执行此操作?

这是完整课程

public class NetworkPacketSerializer
{
    public static IEnumerable<byte> SerializeToBytes(object packet)
    {
        var writer = new NetworkPacketWriter();
        var properties = packet.GetType().GetProperties();

        var identifierAttribute = packet.GetType().GetCustomAttribute<PacketIdAttribute>();

        if (identifierAttribute == null)
        {
            throw new InvalidOperationException($"Missing packet identifier attribute for packet type {packet.GetType()}");
        }
        
        writer.WriteShort(identifierAttribute.I);
        
        foreach (var property in properties)
        {
            WriteProperty(property, writer, packet);
        }

        return writer.GetAllBytes();
    }

    private static void WriteCollectionPropertyToWriter(PropertyInfo propertyInfo, NetworkPacketWriter writer, object packet)
    {
        var properties = propertyInfo.GetType().GetProperties().Where(
            p => Attribute.IsDefined(p, typeof(PacketDataAttribute)));
        
        foreach (var property in properties)
        {
            WriteProperty(property, writer, packet);
        }
    }

    private static void WriteProperty(PropertyInfo property, NetworkPacketWriter writer, object packet)
    {
        if (property.PropertyType == typeof(string))
        {
            writer.WriteString((property.GetValue(packet) as string)!);
        }
        else if (property.PropertyType == typeof(int))
        {
            writer.WriteInteger((int) property.GetValue(packet)!);
        }
        else if (property.PropertyType == typeof(List<>))
        {
            WriteCollectionPropertyToWriter(property, writer, packet);
        }
    }
}
c#
1个回答
0
投票

您可能需要一个

else
分支,它适合所有既不是字符串、不是 int 也不是
List<>
的情况,并迭代这些对象的属性。然后对于每个属性,递归地计算
WriteProperty

private static void WriteProperty(PropertyInfo property, NetworkPacketWriter writer, object packet)
{
    if (property.PropertyType == typeof(string))
    {
        writer.WriteString((property.GetValue(packet) as string)!);
    }
    else if (property.PropertyType == typeof(int))
    {
        writer.WriteInteger((int) property.GetValue(packet)!);
    }
    else if (property.PropertyType == typeof(List<>))
    {
        WriteCollectionPropertyToWriter(property, writer, packet);
    }
    else
    {
        foreach(var p in packet.GetType().GetProperties())
            WriteProperty(p, writer, p.GetValue(packet));
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.