ITemplatePrintable
ITemplatePrintable prints template texts without format provider.
/// <summary>Printable template text where format provider is internally assigned.</summary>
public interface ITemplatePrintable : ITemplatePrintableBase
{
/// <summary>Print <paramref name="arguments"/> in placeholders.</summary>
string Print(object?[]? arguments = null);
/// <summary>Append to <paramref name="sb"/>.</summary>
void AppendTo(StringBuilder sb, object?[]? arguments = null);
/// <summary>Write to <paramref name="textWriter"/>.</summary>
void WriteTo(TextWriter textWriter, object?[]? arguments = null);
/// <summary>Try print <paramref name="arguments"/> into <paramref name="dst"/>.</summary>
/// <param name="length">Number of characters written to <paramref name="dst"/>. If failed, the 0 is returned.</param>
/// <returns>True if text was written, false if write failed.</returns>
bool TryPrintTo(Span<char> dst, out int length, object?[]? arguments = null);
/// <summary>Try estimate print length</summary>
bool TryEstimatePrintLength(out int length, object?[]? arguments = null);
}
/// <summary>Root interface printable template.</summary>
public interface ITemplatePrintableBase
{
/// <summary>Parameters in order of arguments and correspond to arguments and to <see cref="ITemplateParameterPart.ParameterIndex"/>.</summary>
string?[] ParameterNames { get; set; }
}
.WithFormat(culture) adapts ITemplateFormatPrintable to ITemplatePrintable.
ITemplatePrintable printable = new TemplateText("Time is {0}.", TemplateFormat.Brace)
.WithFormat(CultureInfo.CurrentCulture);
Printing
.Print(arguments) prints template string by placing arguments into placeholders.
// Create text without template format
ITemplatePrintable printable = new TemplateText("Time is {0}.", TemplateFormat.Brace).WithFormat(CultureInfo.CurrentCulture);
// Create arguments
object?[] arguments = { DateTime.Now };
// Print ok
string print = printable.Print(arguments);
// ""
WriteLine(print);
.Print(argumentMap) prints from a dictionary of arguments.
// Create text without template format
ITemplatePrintable printable = new TemplateText("Time is {0}.", TemplateFormat.Brace).WithFormat(CultureInfo.CurrentCulture);
// Create arguments
IDictionary<string, object?> argumentMap = new Dictionary<string, object?> { { "0", DateTime.Now } };
// Print ok
string print = printable.Print(argumentMap);
// ""
WriteLine(print);
Printable doesn't expose its inner template string. The implemenation may actually use different template strings, such as a localized or pluralized versions, depending on provided culture and argument values.
// Create localization
ILocalization localization = new Localization()
.AddLine("", "Apple", "Detect", "You've got no apples.", "Unicode.CLDR", "count:cardinal:zero:en")
.AddLine("", "Apple", "Detect", "You've got an apple.", "Unicode.CLDR", "count:cardinal:one:en")
.AddLine("", "Apple", "Detect", "You've got {count} apples.", "Unicode.CLDR", "count:cardinal:other:en");
// Get printable
ITemplatePrintable printable = localization.LocalizableText["Apple"];
// "You have no apples."
WriteLine(printable.Print(new object?[] { 0 }));
// "You have an apple."
WriteLine(printable.Print(new object?[] { 1 }));
// "You have 3 apples."
WriteLine(printable.Print(new object?[] { 3 }));
.EstimatePrintLength(arguments) counts the number of characters and .PrintTo(span, culture, arg) writes to span. This is zero heap printing.
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Create arguments
object[] arguments = { 3 };
// Estimate length
int length = printable.EstimatePrintLength(arguments);
// Allocate span
Span<char> span = length < 512 ? stackalloc char[length] : new char[length];
// Print to span
length = printable.PrintTo(span, arguments);
// Print to stdout, zero heap.
Console.Out.Write(span[..length]);
.EstimatePrintLength(argumentMap) estimates length from a dictionary of arguments.
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Create arguments
IDictionary<string, object?> argumentMap = new Dictionary<string, object?> { { "0", 3 } };
// Estimate length
int length = printable.EstimatePrintLength(argumentMap);
// Allocate span
Span<char> span = length < 512 ? stackalloc char[length] : new char[length];
// Print to span
length = printable.PrintTo(span, argumentMap);
// Print to stdout, zero heap.
Console.Out.Write(span[..length]);
.TryPrintTo(span, arguments) attempts to print without possibility of throwing InvalidOperationException.
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Create arguments
object[] arguments = { 3 };
// Estimate length
int length = printable.EstimatePrintLength(arguments);
// Allocate span
Span<char> span = length < 512 ? stackalloc char[length] : new char[length];
// Print to span
if (printable.TryPrintTo(span, out length, arguments))
Console.Out.Write(span[..length]);
.TryPrintTo(span, argumentMap) attempts to print from a dictionary of arguments.
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Create arguments
IDictionary<string, object?> argumentMap = new Dictionary<string, object?> { { "0", 3 } };
// Estimate length
int length = printable.EstimatePrintLength(argumentMap);
// Allocate span
Span<char> span = length < 512 ? stackalloc char[length] : new char[length];
// Print to span
if (printable.TryPrintTo(span, out length, argumentMap))
Console.Out.Write(span[..length]);
.AppendTo(stringbuilder, arguments) appends to string builder.
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Create arguments
object?[] arguments = { 3 };
// Create string builder
StringBuilder sb = new(1024);
// Append to string builder
printable.AppendTo(sb, arguments);
// Print
WriteLine(sb); // "You have 3 apple(s)."
.AppendTo(stringbuilder, argumentMap) appends from a dictionary of arguments.
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Create arguments
object?[] arguments = { 3 };
// Create string builder
StringBuilder sb = new(1024);
// Append to string builder
printable.AppendTo(sb, arguments);
// Print
WriteLine(sb); // "You have 3 apple(s)."
.WriteTo(textwriter, arguments) writes to text writer.
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Create arguments
object?[] arguments = { 3 };
// Assign text writer
TextWriter textWriter = Console.Out;
// Write to writer
printable.WriteTo(textWriter, arguments); // "You have 3 apple(s)."
.WriteTo(textwriter, argumentMap) writes from a dictionary of arguments.
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Create arguments
IDictionary<string, object?> argumentMap = new Dictionary<string, object?> { { "0", 3 } };
// Assign text writer
TextWriter textWriter = Console.Out;
// Write to writer
printable.WriteTo(textWriter, argumentMap); // "You have 3 apple(s)."
Note
Thanks to C# 10 for Span, stackalloc, ISpanFormattable and MemoryPool which allow zero heap or near zero implementations.
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Rent arguments
object[] arguments = ArrayPool<object>.Shared.Rent(1);
// Assign argument
arguments[0] = "3";
// Estimate length
int length = printable.EstimatePrintLength(arguments);
// Rent chars
char[] buffer = ArrayPool<char>.Shared.Rent(length);
// Print to buffer
length = printable.PrintTo(buffer.AsSpan(), arguments);
// Print to stdout, zero heap.
Console.Out.Write(buffer.AsSpan()[..length]);
// Return rentals
ArrayPool<object>.Shared.Return(arguments);
ArrayPool<char>.Shared.Return(buffer);
Full Example
Full example
using System.Buffers;
using System.Globalization;
using System.Text;
using Avalanche.Localization;
using Avalanche.Template;
using static System.Console;
public class templateprintable
{
public static void Run()
{
{
// <01>
ITemplatePrintable printable = new TemplateText("Time is {0}.", TemplateFormat.Brace)
.WithFormat(CultureInfo.CurrentCulture);
// </01>
}
{
// <03>
// Create text without template format
ITemplatePrintable printable = new TemplateText("Time is {0}.", TemplateFormat.Brace).WithFormat(CultureInfo.CurrentCulture);
// Create arguments
object?[] arguments = { DateTime.Now };
// Print ok
string print = printable.Print(arguments);
// ""
WriteLine(print);
// </03>
}
{
// <03B>
// Create text without template format
ITemplatePrintable printable = new TemplateText("Time is {0}.", TemplateFormat.Brace).WithFormat(CultureInfo.CurrentCulture);
// Create arguments
IDictionary<string, object?> argumentMap = new Dictionary<string, object?> { { "0", DateTime.Now } };
// Print ok
string print = printable.Print(argumentMap);
// ""
WriteLine(print);
// </03B>
}
{
// <04>
// Create localization
ILocalization localization = new Localization()
.AddLine("", "Apple", "Detect", "You've got no apples.", "Unicode.CLDR", "count:cardinal:zero:en")
.AddLine("", "Apple", "Detect", "You've got an apple.", "Unicode.CLDR", "count:cardinal:one:en")
.AddLine("", "Apple", "Detect", "You've got {count} apples.", "Unicode.CLDR", "count:cardinal:other:en");
// Get printable
ITemplatePrintable printable = localization.LocalizableText["Apple"];
// "You have no apples."
WriteLine(printable.Print(new object?[] { 0 }));
// "You have an apple."
WriteLine(printable.Print(new object?[] { 1 }));
// "You have 3 apples."
WriteLine(printable.Print(new object?[] { 3 }));
// </04>
}
{
// <05>
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Create arguments
object[] arguments = { 3 };
// Estimate length
int length = printable.EstimatePrintLength(arguments);
// Allocate span
Span<char> span = length < 512 ? stackalloc char[length] : new char[length];
// Print to span
length = printable.PrintTo(span, arguments);
// Print to stdout, zero heap.
Console.Out.Write(span[..length]);
// </05>
WriteLine();
}
{
// <05B>
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Create arguments
IDictionary<string, object?> argumentMap = new Dictionary<string, object?> { { "0", 3 } };
// Estimate length
int length = printable.EstimatePrintLength(argumentMap);
// Allocate span
Span<char> span = length < 512 ? stackalloc char[length] : new char[length];
// Print to span
length = printable.PrintTo(span, argumentMap);
// Print to stdout, zero heap.
Console.Out.Write(span[..length]);
// </05B>
WriteLine();
}
{
// <06>
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Create arguments
object[] arguments = { 3 };
// Estimate length
int length = printable.EstimatePrintLength(arguments);
// Allocate span
Span<char> span = length < 512 ? stackalloc char[length] : new char[length];
// Print to span
if (printable.TryPrintTo(span, out length, arguments))
Console.Out.Write(span[..length]);
// </06>
WriteLine();
}
{
// <06B>
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Create arguments
IDictionary<string, object?> argumentMap = new Dictionary<string, object?> { { "0", 3 } };
// Estimate length
int length = printable.EstimatePrintLength(argumentMap);
// Allocate span
Span<char> span = length < 512 ? stackalloc char[length] : new char[length];
// Print to span
if (printable.TryPrintTo(span, out length, argumentMap))
Console.Out.Write(span[..length]);
// </06B>
WriteLine();
}
{
// <11>
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Create arguments
object?[] arguments = { 3 };
// Create string builder
StringBuilder sb = new(1024);
// Append to string builder
printable.AppendTo(sb, arguments);
// Print
WriteLine(sb); // "You have 3 apple(s)."
// </11>
}
{
// <11B>
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Create arguments
IDictionary<string, object?> argumentMap = new Dictionary<string, object?> { { "0", 3 } };
// Create string builder
StringBuilder sb = new(1024);
// Append to string builder
printable.AppendTo(sb, argumentMap);
// Print
WriteLine(sb); // "You have 3 apple(s)."
// </11B>
}
{
// <13>
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Create arguments
object?[] arguments = { 3 };
// Assign text writer
TextWriter textWriter = Console.Out;
// Write to writer
printable.WriteTo(textWriter, arguments); // "You have 3 apple(s)."
// </13>
WriteLine();
}
{
// <13B>
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Create arguments
IDictionary<string, object?> argumentMap = new Dictionary<string, object?> { { "0", 3 } };
// Assign text writer
TextWriter textWriter = Console.Out;
// Write to writer
printable.WriteTo(textWriter, argumentMap); // "You have 3 apple(s)."
// </13B>
WriteLine();
}
{
// <20>
// Create template
ITemplatePrintable printable = new TemplateText("You have {0} apple(s).", TemplateFormat.Brace).WithFormat(CultureInfo.InvariantCulture);
// Rent arguments
object[] arguments = ArrayPool<object>.Shared.Rent(1);
// Assign argument
arguments[0] = "3";
// Estimate length
int length = printable.EstimatePrintLength(arguments);
// Rent chars
char[] buffer = ArrayPool<char>.Shared.Rent(length);
// Print to buffer
length = printable.PrintTo(buffer.AsSpan(), arguments);
// Print to stdout, zero heap.
Console.Out.Write(buffer.AsSpan()[..length]);
// Return rentals
ArrayPool<object>.Shared.Return(arguments);
ArrayPool<char>.Shared.Return(buffer);
// </20>
WriteLine();
}
}
}