You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 20:15:08