如何在C#中为泛型参数赋值?优化BitConverter序列化读写代码
C# 规范优化基于BitConverter的数据包序列化流读写代码
我想要编写用于数据包序列化的流读写代码,通过BitConverter对数据类型进行分类并完成读写操作。我初步编写了如下代码,但写法较为稚嫩,请问如何在C#中规范编写这类代码以实现优化?
public int WritePrimitiveType(ArraySegment<byte> stream, int offset, object data) { string data_type = data.GetType().Name; switch (data_type) { case "Boolean": Array.Copy(BitConverter.GetBytes((Boolean)data), 0, stream.Array, stream.Offset + offset, sizeof(Boolean)); return sizeof(Boolean); case "Byte": Array.Copy(BitConverter.GetBytes((Byte)data), 0, stream.Array, stream.Offset + offset, sizeof(Byte)); return sizeof(Byte); case "Int32": Array.Copy(BitConverter.GetBytes((Int32)data), 0, stream.Array, stream.Offset + offset, sizeof(Int32)); return sizeof(Int32); default: return 0; } } public int ReadPrimitiveType<T>(ArraySegment<byte> stream, int offset, ref T data) { switch (typeof(T).Name) { case "Boolean": data = (T)((object)BitConverter.ToBoolean(stream.Array, stream.Offset + offset)); return sizeof(Boolean); case "Byte": data = (T)((object)BitConverter.ToInt16(stream.Array, stream.Offset + offset)); return sizeof(Byte); case "Int32": data = (T)((object)BitConverter.ToInt32(stream.Array, stream.Offset + offset)); return sizeof(Int32); default: data = default(T); return 0; } }
优化方向与规范实现
1. 替换字符串类型判断为直接Type匹配
原代码通过类型名称字符串做分支判断,容易因.NET版本差异、类型别名导致错误,直接用typeof(T)或data.GetType()做判断更可靠。
2. 泛型化Write方法消除装箱开销
原Write方法用object参数会导致值类型装箱,泛型版本能避免这个性能开销,同时增强编译期类型检查。
3. 简化字节写入逻辑,移除冗余Array.Copy
对于单字节类型(如bool、byte)可以直接赋值,无需调用Array.Copy;多字节类型用Buffer.BlockCopy替代Array.Copy,性能更优。
4. 增强错误处理,替换返回0为异常
原代码不支持的类型返回0,调试时难以发现问题,改为抛出明确的NotSupportedException,便于定位问题。
5. 改用out参数替代ref参数(Read方法)
Read方法用out参数更符合C#编码规范,无需提前初始化参数值。
优化后的代码示例
泛型Write方法
public int WritePrimitiveType<T>(ArraySegment<byte> buffer, int offset, T value) { var targetIndex = buffer.Offset + offset; var type = typeof(T); if (type == typeof(bool)) { buffer.Array[targetIndex] = BitConverter.GetBytes((bool)(object)value)[0]; return sizeof(bool); } else if (type == typeof(byte)) { buffer.Array[targetIndex] = (byte)(object)value; return sizeof(byte); } else if (type == typeof(int)) { var bytes = BitConverter.GetBytes((int)(object)value); Buffer.BlockCopy(bytes, 0, buffer.Array, targetIndex, bytes.Length); return bytes.Length; } // 可在此扩展更多支持的 primitive 类型 else { throw new NotSupportedException($"不支持序列化类型: {type.FullName}"); } }
优化后的Read方法
public int ReadPrimitiveType<T>(ArraySegment<byte> buffer, int offset, out T value) { var sourceIndex = buffer.Offset + offset; var type = typeof(T); if (type == typeof(bool)) { value = (T)(object)BitConverter.ToBoolean(buffer.Array, sourceIndex); return sizeof(bool); } else if (type == typeof(byte)) { value = (T)(object)buffer.Array[sourceIndex]; return sizeof(byte); } else if (type == typeof(int)) { value = (T)(object)BitConverter.ToInt32(buffer.Array, sourceIndex); return sizeof(int); } // 可在此扩展更多支持的 primitive 类型 else { value = default; throw new NotSupportedException($"不支持反序列化类型: {type.FullName}"); } }
进阶优化建议
- 改用Span
提升性能 :.NET Core 2.1及以上版本支持Span<byte>,它是栈分配的内存结构,避免数组边界检查开销,性能更优,可替换ArraySegment<byte>。 - 缓存读写委托:如果频繁调用这些方法,可以用
Dictionary<Type, Delegate>缓存每种类型的读写逻辑,避免每次分支判断的开销。 - 明确字节序:如果需要跨平台兼容,不要依赖
BitConverter的默认主机字节序,手动实现大端/小端的字节转换,确保数据在不同架构的设备上正确解析。
内容的提问来源于stack exchange,提问作者asdf qwer
相关产品推荐
相关产品推荐

