快速看懂 ByteSize 源码:一个 long Bits 如何优雅驱动十进制与二进制双体系转换 快速看懂 ByteSize 源码一个 long Bits 如何优雅驱动十进制与二进制双体系转换【免费下载链接】ByteSizeByteSize is a utility class that makes byte size representation in code easier by removing ambiguity of the value being represented. ByteSize is to bytes what System.TimeSpan is to time.项目地址: https://gitcode.com/gh_mirrors/byt/ByteSizeByteSize 是一款 C# 字节大小工具库它让字节单位转换变得清晰无歧义——就像System.TimeSpan之于时间。它的核心设计只有一个思路用一个long Bits字段存储真实值其余所有单位KB、MB、KiB、GiB……全部按需换算而来。今天带你完整剖析这套十进制/二进制双体系转换的源码实现几行关键代码就能看懂。先搞清楚为什么需要 KB 和 KiB 两套体系很多新手第一次会困惑同样是1 KB硬盘厂商说是 1000 字节而 Windows 任务管理器里的内存又按 1024 算。这不是谁错了而是两套标准并存体系换算比例缩写典型场景 十进制SI 标准1 KB 1000 BKB、MB、GB、TB硬盘容量、云存储计费 二进制IEC 标准1 KiB 1024 BKiB、MiB、GiB、TiB内存、内存分配器ByteSize 从 v2.0 起同时支持这两套体系见 CHANGELOG.md 中的破坏性变更记录这也是理解它源码的起点。单一数据源Bits 就是宇宙真理打开核心文件src/ByteSizeLib/ByteSize.cs结构体ByteSize只有两个字段public long Bits { get; } // 唯一整数真值 public double Bytes { get; } // Bits / 8只是缓存构造函数里的逻辑简单到极致ByteSize.cspublic ByteSize(long bits) { Bits bits; Bytes (double)bits / BitsInByte; // BitsInByte 8 }为什么选long而不是double因为位bit是不可再分的最小单位整数存储零精度损失而加减乘除的结果若出现小数字节Bytes用double承接兼顾精度与灵活性。所有比较、相等、排序操作最终都落在Bits上比如CompareTo只有一行this.Bits.CompareTo(other.Bits)。十进制换算5 个常量撑起整个体系src/ByteSizeLib/DecimalByteSize.cs是一个partial 结构体只干一件事——定义十进制换算5 个比例常量BytesInKiloByte 1_000一直到BytesInPetaByte 1_000_000_000_000_0005 个符号常量KB、MB、GB、TB、PB5 个只读属性KiloBytes Bytes / BytesInKiloByte5 个工厂方法FromKiloBytes、FromMegaBytes……全部收敛为new ByteSize(value * 常量)也就是说1.5 MB 并不神秘——它只是1500000 字节的另一种叫法落到 Bits 就是 12000000。二进制换算同样 5 件套只是底数换了src/ByteSizeLib/BinaryByteSize.cs结构与十进制文件完全对称只是常量换成了 1024 的幂常量值BytesInKibiByte1_024BytesInMebiByte1_048_576BytesInGibiByte1_073_741_824BytesInTebiByte1_099_511_627_776BytesInPebiByte1_125_899_906_842_624两个文件合起来ByteSize就拥有了bits、bytes 十进制 5 级 二进制 5 级共 12 个视角但它们读写的始终是同一个Bits。这正是一个 long 驱动双体系的全部秘密没有转换只有除法。自动挑最大整数单位ToString 的精髓用户最在意的输出体验在ToString里ByteSize.cs。它配合LargestWholeNumberDecimalSymbol这类属性从上往下逐级探测找到值 ≥ 1 的最大单位var size ByteSize.FromKiloBytes(1000); size.ToString(); // 1 MB ——十进制视角 size.ToBinaryString(); // 0.98 MiB ——二进制视角细节也很讲究值为 0 时固定输出0 B避免出现诡异的0 b格式化串里写KB、MiB等符号即可强制指定体系数字格式走标准的double.ToString默认0.##保留两位小数且支持区域性de-DE文化下的1,55 kib也能正确解析。字符串解析把 1.55 MB 读回来Parse方法ByteSize.cs采用数字与单位切半策略先找到第一个非数字字符把前半段double.TryParse成数值后半段按 switch 分派b/B大小写敏感——位不允许小数1.5 b会抛FormatExceptionKB、MB走十进制工厂方法KiB、MiB走二进制工厂方法解析失败可用TryParse静默兜底风格与 .NET 基类一致。此外还有一个隐藏彩蛋ByteSize标注了[TypeConverter(typeof(ByteSizeTypeConverter))]src/ByteSizeLib/ByteSizeTypeConverter.cs意味着设计器、配置文件里可以直接写字符串框架自动完成 Parse/ToString。工程组织测试如何保障双体系正确性源码只有 6 个 .cs 文件测试却按体系分得清清楚楚src/ByteSizeLib.Tests/Decimal/—— 十进制方向的算术、构造、解析、字符串测试src/ByteSizeLib.Tests/Binary/—— 二进制方向的同名四件套顶层src/ByteSizeLib.Tests/—— 跨体系的公共行为构建也很轻dotnet build编译、dotnet test跑测试见根目录 Makefile。多目标框架定义在src/ByteSizeLib/ByteSizeLib.csproj通过 netstandard 同时覆盖 .NET Core、.NET Framework 与 UWP。新手避坑指南 ⚠️别把 KB 和 KiB 混用FromKiloBytes(1024)是 1_024_000 字节而FromKibiBytes(1024)是 1_048_576 字节二者相差 2.4%。升级 v1 老代码要小心v1 中KB 1024 Bv2 起KB 1000 B需要 1024 语义时请改用FromKibiBytes。/--自增自减以字节为单位且源码 TODO 注释暗示作者自己也在考虑移除它。乘法/除法返回的仍是 ByteSizeFromBytes(4) * FromBytes(2)得到 8 字节语义上字节乘字节并不常见使用时想清楚即可。总结这套设计的可复用之处单一数据源所有单位都是同一个long的投影永远不会出现KB 属性与 Bytes 属性互相打架partial struct 分文件十进制与二进制各占一文件互不干扰阅读路径清晰常量即文档比例与符号全部public const既可供外部复用又自带说明输出交给 LargestWholeNumber 系列属性UI 展示一行代码搞定还顺带支持本地化。如果你正在写任何涉及容量、带宽、存储配额的 C# 程序这套一个长整型 双向换算表的模式几乎可以直接抄进自己的领域模型里。【免费下载链接】ByteSizeByteSize is a utility class that makes byte size representation in code easier by removing ambiguity of the value being represented. ByteSize is to bytes what System.TimeSpan is to time.项目地址: https://gitcode.com/gh_mirrors/byt/ByteSize创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考