Built-in converter catalog
Every type that TomlSerializer handles without a user converter is served by a built-in converter - internally an ordinary TomlConverter<T>. This page catalogs that set - which .NET types are provisioned, how each is represented on the wire, and what the read path accepts. Resolution order and the rules for overriding a built-in with your own converter are covered in Writing converters. The sibling libraries (Bodu.Text.Bencode, Bodu.Text.Yaml) ship their own catalog over the same machinery.
The design is: exact-type scalar converters first, factories for open type families (nullables, enums, dictionaries, collections, plain objects) last, with the document object model bridges ahead of everything so a DOM value is never claimed by a structural factory. The full ordering, top to bottom, is:
- the DOM bridges -
TomlNode,TomlElement,TomlDocument- so a DOM value always flows through its own bridge rather than the dictionary or object factory; - the exact-type scalar converters (
string,bool,char,Guid,Uri,Version,TimeSpan,double,float,Half,decimal, and the four date-time types), so a scalar is never captured by the object factory; - the byte-array and memory-of-byte converters, ahead of the collection factory so binary data maps by its dedicated converter rather than as a sequence of integers;
- the integer, enum, and nullable factories;
- the dictionary factory ahead of the collection factory, so a string-keyed dictionary becomes a table rather than a collection;
- the
objectconverter, so anobject-typed member dispatches on its runtime type instead of mapping to an empty table; - the object factory last, as the catch-all that writes a plain class or struct as a table.
A user converter, or a converter named by a [Converter] attribute, is consulted ahead of this entire list - see Writing converters for the precedence ladder.
Scalars
| .NET type | TOML representation (write) | Read accepts | Notes |
|---|---|---|---|
string |
string | string | |
bool |
boolean | boolean | |
char |
single-character string | single-character string | Multi-character strings are rejected. |
Guid |
string, canonical 36-character D format |
D-format string |
|
Uri |
string, the original URI text | string | Relative and absolute URIs round-trip. |
Version |
string, the component form ("1.2.3.4") |
version string | Leading/trailing whitespace is rejected. |
TimeSpan |
string, invariant constant format ("1.02:03:04.5670000") |
"c"-format string |
The round-trippable constant format. |
double |
float (including inf / -inf / nan) |
float | |
float |
float | float | Widens to binary64 on write; narrows on read. |
Half |
float | float | Exact widening on write; saturating IEEE 754 narrow on read - an out-of-range finite float reads back as ±infinity. |
decimal |
float or invariant string, per TomlDecimalHandling | float, integer, or string | Float (default) is native but lossy beyond binary64; String round-trips all 28 digits. Read accepts all three forms regardless of the setting. |
sbyte byte short ushort int uint long ulong nint nuint |
integer | integer | Checked conversions; a value outside the target type or TOML's signed 64-bit range is a serialization error. |
Int128 / UInt128 |
integer | integer | Confined by checked conversion to the signed 64-bit range TOML stores; larger values throw on write. |
DateTimeOffset |
offset date-time | offset date-time | |
DateTime |
local date-time (Unspecified) or offset date-time (Utc / Local) |
matching kind | Kind-aware on write. |
DateOnly |
local date | local date | |
TimeOnly |
local time | local time | |
enum (any) |
string, the member name | string (case-insensitive) or integer | Per-member names via [StringEnumMemberName]; see the enum converters below. |
Binary data
| .NET type | TOML representation (write) | Read accepts | Notes |
|---|---|---|---|
byte[] |
integer array or Base64 string, per TomlByteArrayHandling | either form | Default is the integer array. |
Memory<byte> / ReadOnlyMemory<byte> |
same as byte[] |
either form | Shares the byte-array logic and setting. |
Structural and document-model types
| .NET type | TOML representation | Notes |
|---|---|---|
Nullable<T> |
underlying type's form | TOML has no null; a null member is omitted before any converter runs. |
arrays, List<T>, list interfaces, concrete ICollection<T>, Queue<T> / Stack<T> / ConcurrentQueue<T> / ConcurrentStack<T> / ConcurrentBag<T> |
array | A Stack<T> round-trip reverses: the writer emits pop order. |
dictionaries with string, integer, enum, Guid, bool, or char keys |
table | Non-string keys are written in invariant text. The newer scalars (Version, TimeSpan, decimal, Half, 128-bit integers) are deliberately not key types. |
| plain classes and structs | table | The catch-all object converter, consulted last. |
object-typed members |
runtime type's form on write; TomlElement on read | A bare new object() writes an empty table; null members are omitted. |
TomlNode (and TomlObject / TomlArray / TomlValue) |
the node's own kind | Mutable DOM bridge. |
| TomlElement | the element's own kind | Read produces an element backed by an internal, garbage-collected document - no disposal needed. |
| TomlDocument | the document's root | A deserialized document is caller-owned: dispose it when finished. |
Public enum converters
Registered on the options or referenced from a [Converter(...)] attribute:
- TomlStringEnumConverter /
TomlStringEnumConverter<TEnum>- member-name strings with an optional naming policy and integer-on-read flag. TomlNumberEnumConverter<TEnum>- the underlying numeric value as a TOML integer.
Representation decisions at a glance
TOML's native scalar kinds - string, integer, float, boolean, and the four date-time forms - cover nearly every common BCL type without a choice to make. Two types carry a representation selector on the options:
| Type | Selector | Forms |
|---|---|---|
decimal |
TomlDecimalHandling | native float (default, binary64-bounded) or a lossless invariant string |
byte[] / memory-of-byte |
TomlByteArrayHandling | integer array (default) or a Base64 string |
The document root must map to a table, so a top-level scalar or array throws. The object / element / document bridges let a DOM value flow through the serializer untouched.
See also
- Writing converters - overriding a built-in, factories, and resolution order.
- Using TOML - the format walk-through the tables above back up.
- Mapping attributes - the declarative layer over the converters.
- Core concepts - the value-mapping summary in the family vocabulary.
- Text & Serialization guides and the topic overview.
- API reference - TomlConverter<T>, TomlByteArrayHandling, TomlDecimalHandling.