ModelingEvolution.Bytes
3.0.0
dotnet add package ModelingEvolution.Bytes --version 3.0.0
NuGet\Install-Package ModelingEvolution.Bytes -Version 3.0.0
<PackageReference Include="ModelingEvolution.Bytes" Version="3.0.0" />
<PackageVersion Include="ModelingEvolution.Bytes" Version="3.0.0" />
<PackageReference Include="ModelingEvolution.Bytes" />
paket add ModelingEvolution.Bytes --version 3.0.0
#r "nuget: ModelingEvolution.Bytes, 3.0.0"
#:package ModelingEvolution.Bytes@3.0.0
#addin nuget:?package=ModelingEvolution.Bytes&version=3.0.0
#tool nuget:?package=ModelingEvolution.Bytes&version=3.0.0
ModelingEvolution.Bytes
A high-performance struct for representing byte sizes with human-readable formatting, arithmetic operations, and full serialization support including dictionary key compatibility.
Features
- Value type struct - Stack allocated, efficient, and thread-safe
- Human-readable formatting - Automatically formats as "1.5 KB", "2.3 MB", etc.
- Full arithmetic support - Addition, subtraction, multiplication, division
- Implicit conversions - Seamlessly convert between numeric types and Bytes
- Parsing support - Parse strings like "1.5GB" or "2048"
- JSON serialization - Full support including use as dictionary keys
- DataContract support - XML/Binary serialization without ProtoBuf dependencies
- Zero allocations - Optimized for performance
- Cross-platform - Targets .NET 8.0 and .NET 9.0
Installation
dotnet add package ModelingEvolution.Bytes
Quick Start
using ModelingEvolution;
// Create from numeric values
Bytes size1 = 1024; // 1 KB
Bytes size2 = new Bytes(1536); // 1.5 KB
Bytes size3 = Bytes.FromFile("file.txt");
// Parse from strings
Bytes size4 = "2.5 GB"; // Implicit conversion
Bytes size5 = Bytes.Parse("100 MB");
// Arithmetic operations
var total = size1 + size2; // 2.5 KB
var difference = size2 - size1; // 512 bytes
var scaled = size1 * 4; // 4 KB
var divided = size2 / 2; // 768 bytes
// Display formatting
Console.WriteLine(size2); // "1.5 KB"
long rawBytes = size2; // 1536 (implicit conversion)
// Comparisons
if (size1 < size2)
Console.WriteLine("size1 is smaller");
// Use in collections
var dictionary = new Dictionary<Bytes, string>
{
[Bytes.Parse("1GB")] = "Large file",
[Bytes.Parse("1MB")] = "Small file"
};
JSON Serialization
The Bytes
struct includes full JSON support with a custom converter that handles both regular serialization and dictionary key scenarios:
using System.Text.Json;
// Simple serialization
var bytes = new Bytes(1024);
var json = JsonSerializer.Serialize(bytes); // "1024"
var deserialized = JsonSerializer.Deserialize<Bytes>(json);
// As dictionary keys
var dict = new Dictionary<Bytes, string>
{
[new Bytes(1024)] = "Config",
[new Bytes(1048576)] = "Data"
};
var dictJson = JsonSerializer.Serialize(dict);
// {"1024":"Config","1048576":"Data"}
// Complex objects
public class FileInfo
{
public string Name { get; set; }
public Bytes Size { get; set; }
}
var file = new FileInfo { Name = "video.mp4", Size = "1.5GB" };
var fileJson = JsonSerializer.Serialize(file);
DataContract Serialization
Full support for WCF/XML serialization without ProtoBuf dependencies:
using System.Runtime.Serialization;
[DataContract]
public class Document
{
[DataMember]
public string Title { get; set; }
[DataMember]
public Bytes FileSize { get; set; }
}
// XML serialization works out of the box
var serializer = new DataContractSerializer(typeof(Document));
Protobuf Serialization
Full support for Protobuf-net serialization - works directly with no configuration needed:
using ProtoBuf;
[ProtoContract]
public class FileInfo
{
[ProtoMember(1)]
public string Name { get; set; }
[ProtoMember(2)]
public Bytes Size { get; set; } // Works directly!
}
// Serialize with Protobuf
var file = new FileInfo { Name = "video.mp4", Size = "1.5GB" };
using var stream = new MemoryStream();
Serializer.Serialize(stream, file);
The Bytes
struct uses [DataContract]
attributes which Protobuf-net recognizes, enabling seamless serialization.
Parsing Formats
The parser supports various formats with case-insensitive suffixes:
// Numeric values
Bytes.Parse("1024") // 1024 bytes
Bytes.Parse("1,024") // 1024 bytes (with thousands separator)
// With size suffixes
Bytes.Parse("1KB") // 1024 bytes
Bytes.Parse("1 KB") // 1024 bytes (with space)
Bytes.Parse("1.5MB") // 1572864 bytes
Bytes.Parse("2.5 GB") // 2684354560 bytes
// Case insensitive
Bytes.Parse("1kb") // 1024 bytes
Bytes.Parse("1Kb") // 1024 bytes
// Supported suffixes
// B, KB, MB, GB, TB, PB, EB
Implicit Conversions
The struct provides extensive implicit conversion support:
// From numeric types to Bytes
Bytes fromInt = 1024;
Bytes fromUint = 2048u;
Bytes fromLong = 1099511627776L;
Bytes fromUlong = 1125899906842624UL;
Bytes fromString = "1.5KB";
// From Bytes to numeric types
int intValue = new Bytes(1024);
uint uintValue = new Bytes(2048);
long longValue = new Bytes(1099511627776L);
ulong ulongValue = new Bytes(1125899906842624L);
double doubleValue = new Bytes(1536);
Performance Considerations
- Readonly struct: Prevents defensive copies and ensures thread-safety
- Value type: Stack allocated, no GC pressure
- Optimized formatting: Caches formatted strings when precision is specified
- Zero allocations: Parse and format operations minimize allocations
Thread Safety
The Bytes
struct is immutable and thread-safe. All operations create new instances rather than modifying existing ones.
Examples
File Size Analysis
var files = Directory.GetFiles(@"C:\MyFolder")
.Select(f => new { Path = f, Size = Bytes.FromFile(f) })
.OrderByDescending(f => f.Size)
.Take(10);
foreach (var file in files)
Console.WriteLine($"{file.Path}: {file.Size}");
Configuration with Size Limits
public class UploadConfig
{
public Bytes MaxFileSize { get; set; } = "100MB";
public Bytes MaxTotalSize { get; set; } = "1GB";
public bool IsAllowed(Bytes fileSize)
=> fileSize <= MaxFileSize;
}
Progress Tracking
public class DownloadProgress
{
public Bytes Downloaded { get; private set; }
public Bytes Total { get; private set; }
public double PercentComplete =>
(long)Total > 0 ? (double)Downloaded / Total * 100 : 0;
public void Update(Bytes bytesReceived)
{
Downloaded += bytesReceived;
Console.WriteLine($"Downloaded: {Downloaded} / {Total} ({PercentComplete:F1}%)");
}
}
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support
For issues and feature requests, please use the GitHub issue tracker.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- System.Text.Json (>= 9.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
3.0.0 | 129 | 9/3/2025 |
2.0.0 | 125 | 9/3/2025 |
1.0.0 | 125 | 9/3/2025 |
1.0.0-master-fded46a | 124 | 9/3/2025 |
1.0.0-master-9935042 | 126 | 9/3/2025 |
1.0.0-master-797de36 | 125 | 9/3/2025 |
1.0.0-master-776661f | 122 | 9/3/2025 |
1.0.0-master-6e3c4bc | 122 | 9/3/2025 |
1.0.0-master-4b2ca70 | 127 | 9/3/2025 |
1.0.0-master-1257dad | 128 | 9/3/2025 |
1.0.0-master-102efde | 126 | 9/3/2025 |