我正在尝试为我的类编写一个序列化器,以便任何属性都映射到字节编写器。我需要循环遍历实际列表中每个项目的
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);
}
}
}
您可能需要一个
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));
}
}