TooString 0.5.0-preview
dotnet add package TooString --version 0.5.0-preview
NuGet\Install-Package TooString -Version 0.5.0-preview
<PackageReference Include="TooString" Version="0.5.0-preview" />
<PackageVersion Include="TooString" Version="0.5.0-preview" />
<PackageReference Include="TooString" />
paket add TooString --version 0.5.0-preview
#r "nuget: TooString, 0.5.0-preview"
#addin nuget:?package=TooString&version=0.5.0-preview&prerelease
#tool nuget:?package=TooString&version=0.5.0-preview&prerelease
TooString is a Stringifier that goes places serializers don't.
TooString() can
- make a best effort to stringify objects that JsonSerializer won't, including System.Reflection classes and System.Type, or that JsonSerializer surprises you with, such as ValueTuples.
- Output as Json, or ‘debug view’ style, or as [CallerArgumentExpression]
TooString offers 3 extension method groups on Object:
value.TooString();
value.ToJson();
value.ToDebugViewString();
TooString is not a serializer. A serializer should be fail-fast, but TooString is best-effort. A Serializer should throw if it cannot deterministically serialize the input, but TooString will attempt to return a partial or alternative representation of the input even when input cannot reliably be serialized.
Default behaviour
- ToJson() defaults to using System.Text.Json, falling back to reflection for un-serializable types. whereas
- TooString(ReflectionStyle.Json)
- TooString(ReflectionStyle.DebugView)
- ToDebugView() all defaults to MaxDepth = 4, MaxEnumerationLength = 9.
Example:
var value = new { A = "boo", B = new Complex(3,4) };
value.ToJson(); // Output Is System.Text.Json {"A":"boo","B":{"Real":3,"Imaginary":...}}
value.ToDebugViewString(),//Output is { A = boo, B = <3; 4> } depending on .Net version.
( Math.Sqrt(4 * Math.PI / 3) ).TooString( TooStringHow.CallerArgument )
// Output is the literal code: "Math.Sqrt(4 * Math.PI / 3)"
var tuple = (one: 1, two: "2", three: new Complex(3,4));
System.Text.Json.JsonSerializer.Serialize(tuple) // Output is "{}" because there
// are no public properties on a tuple
tuple.TooString(ReflectionStyle.Json)
// Output is created by reflection and stringifies the tuple and the Complex number as arrays
// [1,"2",[3,4]]
tuple.ToDebugViewString()
tuple.TooString(TooStringHow.Reflection)
// Output is created by reflection and mimics typical debugger display
// on Net6.0: {item1 = 1, item2 = "2", item3 = (3,4)}
// on Net8.0: {item1 = 1, item2 = "2", item3 = <3;4>}
var type = value.GetType();
System.Text.Json.JsonSerializer.Serialize(type) // Throws NotSupportedException
type.ToJson() // Outputs truncated Json with default MaxDepth = 4, MaxEnumerationLength = 9
Options
Options are finicky because we can do either Json serialization, or Reflection-based stringification with Json output or with Debugview output, or CallerArgumentExpression. For Json serialization, the options are System.Text.Json.JsonSerializationOptions. For Reflection-based output, there are options for MaxDepth, but also MaxLength (of enumerable display), and for DateTime, DateOnly, TimeOnly, and TimeSpan formatting.
Try one of these approaches:
// For Json using STJ
value.ToJson()
value.TooString( new JsonSerializerOptions(JsonSerializerDefaults.Web){WriteIndented = true})
// For Json using Reflection
value.TooString( ReflectionStyle.Json )
value.TooString( ReflectionOptions.ForJson with {} )
// For DebugView
value.ToDebugViewString()
value.TooString( ReflectionStyle.DebugView )
value.TooString( ReflectionOptions.ForDebugView.With(...) ) // Same output as value.ToDebugViewString()
value.TooString( maxDepth:4, maxLength:9, style:ReflectionStyle.DebugView )
value.TooString( ReflectionOptions.ForDebugView with
{
DateTimeFormat = "yyyyMMdd HH:mm:ss",
TimeSpanFormat = @"d\.hh\:mm\:ss"
})
// For Either
value.TooString( TooStringOptions.Default with { ... } )
//CallerArgumentExpression will automatically be chosen if the expression is not just a name:
(1 + value).TooString()
Gotchas
Example: Json-serializing value tuples is something of a surprise because (unlike anonymous objects or records or structs) they have no public properties and their public fields are not named as per your code. Takeaway: don't choose value tuples for public apis that must be jsonned.
Use modifications of TooStringOptions.Default
to customise the results.
System.Text.Json.JsonSerializer.Serialize( (one:1, two:"2") )
// Output is "{}" because there are no public fields
(one:1, two:"2").TooString( TooStringHow.Json )
// Output is [1,"2"].
// The value tuple is detected as an ITuple, and we use reflection instead
ChangeLog
<pre> ChangeLog
0.5.0 ReflectionOptions.With(...), TooStringOptions.With(...). Fixes. 0.4.0 ReflectionOptions.MaxLength default = 9 ReflectionOptions.ForJson and ReflectionOptions.ForDebugView instead of Default. More overloads. 0.3.0 ReflectionOptions.MaxLength limits display of enumerable elements 0.2.0 Added Net8 (NB Net8 Json and Numerics output is different from Net6) Rename TooStringStyle to TooStringHow. Fix SerializationStyle.Reflection output of DateTime, DateOnly, TimeOnly. 0.1.0 Can use DebugView, Json, ToString() or [CallerArgumentExpression] and can output Json or Debug strings. </pre>
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. 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 is compatible. 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. |
-
net6.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on TooString:
Package | Downloads |
---|---|
TestBase
*TestBase* gives you a flying start with - fluent assertions that are easy to extend - sharp error messages - tools to help you test with “heavyweight” dependencies on - AspNetCore.Mvc, AspNet.Mvc or WebApi Contexts - HttpClient - Ado.Net - Streams & Logging - Mix & match with your favourite test runners & assertions. ``` UnitUnderTest.Action() .ShouldNotBeNull() .ShouldEqualByValueExceptFor(new {Id=1, Descr=expected}, ignoreList ) .Payload .ShouldMatchIgnoringCase("I expected this") .Should(someOtherPredicate); .Items .ShouldAll(predicate) .ShouldContain(item) .ShouldNotContain(predicate) .Where(predicate) .SingleOrAssertFail() .ShouldEqualByValue().ShouldEqualByValueExceptFor(...).ShouldEqualByValueOnMembers() work with all kinds of object and collections, and report what differed. string.ShouldMatch(pattern).ShouldNotMatch().ShouldBeEmpty().ShouldNotBeEmpty() .ShouldNotBeNullOrEmptyOrWhiteSpace().ShouldEqualIgnoringCase() .ShouldContain().ShouldStartWith().ShouldEndWith().ShouldBeContainedIn(), ... numeric.ShouldBeBetween().ShouldEqualWithTolerance()....GreaterThan....LessThan...GreaterOrEqualTo ... ienumerable.ShouldAll().ShouldContain().ShouldNotContain().ShouldBeEmpty().ShouldNotBeEmpty() ... stream.ShouldHaveSameStreamContentAs().ShouldContain() value.ShouldBe().ShouldNotBe().ShouldBeOfType().ShouldBeAssignableTo()... ``` Testable Logging is in packages Extensions.Logging.ListOfString and Serilog.Sinks.ListOfString ``` // Extensions.Logging.ListOfString var log = new List<String>(); ILogger mslogger= new LoggerFactory().AddStringListLogger(log).CreateLogger("Test2"); // Serilog.Sinks.ListOfString Serilog.Logger slogger= new LoggerConfiguration().WriteTo.StringList(log).CreateLogger(); ``` |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
0.5.0-preview | 113 | 6/30/2025 |
0.4.0-preview | 562 | 6/24/2025 |
0.3.0-preview | 159 | 6/24/2025 |
0.2.0-preview | 128 | 6/20/2025 |
0.1.0 | 1,857 | 7/11/2024 |
ChangeLog
---------
0.5.0 ReflectionOptions.MaxEnumerationLength renamed from MaxLength | Options.With(...) methods for easy configuration
0.4.0 ReflectionOptions.MaxLength default = 9 | ReflectionOptions.ForJson and ReflectionOptions.ForDebugView instead of Default | More overloads.
0.3.0 ReflectionOptions.MaxLength limits display of enumerable elements
0.2.0 Added Net8 (NB Net8 Json and Numerics output is different from Net6)
Rename TooStringStyle to TooStringHow.
Fix SerializationStyle.Reflection output of DateTime, DateOnly, TimeOnly.
0.1.0 Can use DebugView, Json, ToString() or [CallerArgumentExpression] and can output Json or Debug strings.