UWP中泛型<T>与byte[]互转及PacketData对象序列化还原
实现PacketData的序列化与反序列化(UWP Socket传输)
要支持泛型Data属性的字节数组转换,需要在现有逻辑基础上添加泛型对象的序列化/反序列化处理。以下是修改后的完整实现:
修改后的代码
using System; using System.Collections.Generic; using System.Text; using System.Text.Json; class School { public int Id { get; set; } public string Name { get; set; } } class PacketData<T> { // 默认构造函数 public PacketData() { cmdCommand = Command.Null; StringData = null; strName = null; Data = default; } // 从byte[]反序列化构造 public PacketData(byte[] data) { int offset = 0; // 读取Command(4字节) cmdCommand = (Command)BitConverter.ToInt32(data, offset); offset += 4; // 读取strName长度(4字节) int nameLen = BitConverter.ToInt32(data, offset); offset += 4; // 读取StringData长度(4字节) int msgLen = BitConverter.ToInt32(data, offset); offset += 4; // 读取strName strName = nameLen > 0 ? Encoding.UTF8.GetString(data, offset, nameLen) : null; offset += nameLen; // 读取StringData StringData = msgLen > 0 ? Encoding.UTF8.GetString(data, offset, msgLen) : null; offset += msgLen; // 读取Data字节长度(4字节) int dataLen = BitConverter.ToInt32(data, offset); offset += 4; // 反序列化Data if (dataLen > 0) { Data = JsonSerializer.Deserialize<T>(data.AsSpan(offset, dataLen)); } else { Data = default; } } // 序列化为byte[] public byte[] ToByte() { List<byte> result = new List<byte>(); // 添加Command result.AddRange(BitConverter.GetBytes((int)cmdCommand)); // 添加strName长度和内容 int nameLen = strName?.Length ?? 0; result.AddRange(BitConverter.GetBytes(nameLen)); if (nameLen > 0) { result.AddRange(Encoding.UTF8.GetBytes(strName)); } // 添加StringData长度和内容 int msgLen = StringData?.Length ?? 0; result.AddRange(BitConverter.GetBytes(msgLen)); if (msgLen > 0) { result.AddRange(Encoding.UTF8.GetBytes(StringData)); } // 添加Data的字节数组长度和内容 byte[] dataBytes = Data == null ? Array.Empty<byte>() : JsonSerializer.SerializeToUtf8Bytes(Data); result.AddRange(BitConverter.GetBytes(dataBytes.Length)); result.AddRange(dataBytes); return result.ToArray(); } public string strName; // 客户端登录名称 public string StringData; // 文本消息 public Command cmdCommand; // 命令类型 public T Data; // 泛型数据 } enum Command { Login, // 登录服务器 Logout, // 登出服务器 Message, // 发送文本消息给所有客户端 List, // 获取聊天室用户列表 Null } static void Main(string[] args) { // 示例:构造带泛型Data的PacketData var school = new School { Id = 1, Name = "Test Name" }; var packetData = new PacketData<School> { cmdCommand = Command.Login, strName = "Login Data", Data = school, StringData = null }; // 序列化为byte[] byte[] message = packetData.ToByte(); // 从byte[]反序列化回PacketData<T> PacketData<School> msgReceived = new PacketData<School>(message); // 验证结果 Console.WriteLine($"Command: {msgReceived.cmdCommand}"); Console.WriteLine($"Name: {msgReceived.strName}"); Console.WriteLine($"School Id: {msgReceived.Data.Id}, Name: {msgReceived.Data.Name}"); }
关键说明
- 序列化方式选择:使用
System.Text.Json进行泛型对象的序列化/反序列化,无需给实体类添加额外特性,UWP环境支持良好,且性能优异。 - 字节结构规范:统一按「长度标识+内容」的格式存储可变长度数据(字符串、泛型对象),确保反序列化时能准确定位各字段的字节范围:
- Command(固定4字节)
- strName长度(4字节)+ strName内容(可变长度)
- StringData长度(4字节)+ StringData内容(可变长度)
- Data字节长度(4字节)+ Data序列化后的字节内容(可变长度)
- 空值处理:针对所有可空字段(strName、StringData、Data)做了空值判断,避免序列化/反序列化时出现异常。
- UWP适配:
System.Text.Json是UWP官方推荐的序列化库,无需额外引用,直接使用即可。
内容的提问来源于stack exchange,提问作者SHIFAS KS
相关产品推荐
相关产品推荐

