ModelingEvolution.Bytes 3.0.0

dotnet add package ModelingEvolution.Bytes --version 3.0.0
                    
NuGet\Install-Package ModelingEvolution.Bytes -Version 3.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ModelingEvolution.Bytes" Version="3.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ModelingEvolution.Bytes" Version="3.0.0" />
                    
Directory.Packages.props
<PackageReference Include="ModelingEvolution.Bytes" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ModelingEvolution.Bytes --version 3.0.0
                    
#r "nuget: ModelingEvolution.Bytes, 3.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ModelingEvolution.Bytes@3.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ModelingEvolution.Bytes&version=3.0.0
                    
Install as a Cake Addin
#tool nuget:?package=ModelingEvolution.Bytes&version=3.0.0
                    
Install as a Cake Tool

ModelingEvolution.Bytes

NuGet NuGet Downloads Build Status License

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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