TinyString 0.2.0

dotnet add package TinyString --version 0.2.0
                    
NuGet\Install-Package TinyString -Version 0.2.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="TinyString" Version="0.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TinyString" Version="0.2.0" />
                    
Directory.Packages.props
<PackageReference Include="TinyString" />
                    
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 TinyString --version 0.2.0
                    
#r "nuget: TinyString, 0.2.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 TinyString@0.2.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=TinyString&version=0.2.0
                    
Install as a Cake Addin
#tool nuget:?package=TinyString&version=0.2.0
                    
Install as a Cake Tool

TinyString

Logo

Turn any .NET object into a readable string. Zero config for simple cases, a clean fluent API when you want more.

dotnet add package TinyString

Zero config

Call .Stringify() on anything:

using TinyString;

var book = new Book { Title = "1984", Author = "George Orwell", Pages = 328 };
book.Stringify();
// → "Book. Title: 1984, Author: George Orwell, Pages: 328"

All public properties, declaration order, class name as header, floats at 2 decimal places. No setup required.


Fluent API

Pass a configuration action when you need more control. Everything lives at the call site — your classes stay clean:

zoo.Stringify(o => o
    .MultiLine()
    .Label("🦁 Zoo")
    .For(x => x.EntrancePrice).Prefix("$").Decimals(0));
🦁 Zoo
Name: Woodland Zoo
EntrancePrice: $15
Animals:
|_ Animal. Name: Mittens, Species: Cat, Weight: 4.50
|_ Animal. Name: Tony, Species: Tiger, Weight: 120.30

In multi-line mode, collections are automatically rendered with |_ per item. In single-line mode they're joined with ", ". No extra configuration needed.


Options

Global

Method What it does Default
.MultiLine() / .SingleLine() Layout style single-line
.Label("…") Replace the class name header class name
.NoLabel() Hide the header entirely
.Separator("…") Between properties in single-line ", "
.CollectionSeparator("…") Override the auto collection separator auto
.Decimals(n) Decimal places for floats 2
.Keys(NamingFormat.X) Key naming style PascalCase
.NullAs("…") Token used for null values "null"
.Only(x => x.A, x => x.B) Whitelist — show only these properties all

Collection items are rendered based on the active style: joined with ", " in single-line, or on their own line prefixed with |_ in multi-line. Multi-line items are indented to align under the prefix, so nested structures stay readable at any depth.

Available naming formats: PascalCase, CamelCase, SnakeCase, KebabCase, HumanCase.

Per property

Chain .For(x => x.Prop) to configure a specific property, then keep chaining .For() to move to the next one:

animal.Stringify(o => o
    .NoLabel()
    .Separator(" ")
    .For(x => x.Name).NoKey()
    .For(x => x.Species).Prefix("(").Suffix(")").NoKey()
    .For(x => x.Weight).NoKey().Suffix("kg").Decimals(2)
    .For(x => x.Age).NoKey().Suffix("yrs")
    .For(x => x.IsRare).Ignore());
// → "Mittens (Cat) 4.50kg 5yrs"
Method What it does
.Ignore() Exclude this property
.As("…") Rename the key
.NoKey() Show only the value
.Prefix("…") / .Suffix("…") Wrap the value
.Separator("…") Collection separator for this property
.Decimals(n) Decimal places for this property
.MaxItems(n) Truncate a collection; appends "... and N more"
.When(v => …) Show only when the predicate is true
.ValueFormat(v => …) Full control over value rendering

.Only() is the shorthand for whitelisting a few properties without chaining multiple .Ignore() calls:

animal.Stringify(o => o.Only(x => x.Name, x => x.Species));
// → "Animal. Name: Mittens, Species: Cat"

Nested objects

Nested objects are rendered using the first match in this priority order:

  1. A ForNested<T>() configuration registered on the parent
  2. An overridden ToString() on the nested type
  3. Reflection over public properties (same defaults as zero-config)
var order = new Order { Product = new Product { Name = "Book", Price = 12.99 }, Qty = 2 };
order.Stringify();
// → "Order. Product: Product. Name: Book, Price: 12.99, Qty: 2"

ForNested

Configure a nested type directly from the root call. The configuration applies wherever that type appears — as a property or inside a collection:

zoo.Stringify(o => o
    .MultiLine()
    .ForNested<Animal>(a => a
        .NoLabel()
        .Separator(" ")
        .For(x => x.Name).NoKey()
        .For(x => x.Species).Prefix("(").Suffix(")").NoKey()
        .For(x => x.Weight).NoKey().Suffix("kg"))
    .For(x => x.EntrancePrice).Prefix("$").Decimals(0));
Zoo
EntrancePrice: $15
Animals:
|_ Mittens (Cat) 4.50kg
|_ Tony (Tiger) 120.30kg

ToString()

If a nested type overrides ToString(), that is used automatically. If ToString() calls Stringify(), it recurses:

public class Animal
{
    public string Name { get; set; }
    public string Species { get; set; }

    public override string ToString() => this.Stringify(o => o
        .NoLabel()
        .For(x => x.Name).NoKey()
        .For(x => x.Species).Prefix("(").Suffix(")").NoKey());
    // → "Mittens (Cat)"
}

Migrating from the attribute API

Previous versions configured stringification via [Stringify], [StringifyProperty], and [StringifyIgnore] attributes. These still work but are deprecated and will be removed in a future major version. Move the configuration to the .Stringify() call site instead.


MIT License

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  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. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.1

    • No dependencies.

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
0.2.0 246 3/31/2026
0.1.0 72 3/31/2026
0.0.3 18,455 6/19/2025
0.0.2 209 6/19/2025
0.0.1 217 6/19/2025