.NET
string templating
C#
programming
software development

What's a good way of doing string templating in .NET?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

The best string templating approach in .NET depends on where the template comes from and how dynamic it needs to be. For templates written directly in code, string interpolation is usually the cleanest option; for reusable external templates, a proper templating engine such as Razor or Scriban is usually a better fit than trying to assemble strings manually.

Best Choice for Code-Owned Templates

If the template is short and lives in your C# source code, interpolation is hard to beat for readability.

csharp
1var userName = "Mark";
2var orderCount = 3;
3
4string message = $"Hello {userName}, you have {orderCount} open orders.";
5Console.WriteLine(message);

This is type-safe, readable, and compile-time checked. It also supports standard formatting:

csharp
1var total = 129.95m;
2var createdAt = new DateTime(2026, 3, 7, 14, 30, 0);
3
4string summary = $"Total: {total:C} at {createdAt:yyyy-MM-dd HH:mm}";
5Console.WriteLine(summary);

For many application messages, that is the right answer.

Reusable Positional Templates with string.Format

When the template is stored as a resource string or reused across multiple call sites, string.Format is still a reasonable choice.

csharp
1string template = "Hello {0}, your shipment {1} is scheduled for {2:yyyy-MM-dd}.";
2string message = string.Format(template, "Mark", "SH-204", DateTime.UtcNow);
3
4Console.WriteLine(message);

This is common in localization scenarios where translators edit resource entries. The downside is readability: positional placeholders become harder to maintain as the template grows.

When You Need Named Placeholders

If non-developers edit templates, named fields are easier to understand than numbered placeholders. At that point, it is usually better to adopt a real templating library rather than implementing homegrown Replace chains.

Scriban is a popular lightweight option:

csharp
1using Scriban;
2
3var template = Template.Parse("Hello {{ name }}, your order total is {{ total }}.");
4var result = template.Render(new { name = "Mark", total = 129.95m });
5
6Console.WriteLine(result);

A library like this gives you named fields, escaping rules, loops, and conditional output without turning your code into brittle string surgery.

Razor for Rich Markup Templates

If the output is HTML or email content and you want familiar .NET syntax, Razor-based templating can be a good fit.

csharp
@model WelcomeEmailModel
<h1>Hello @Model.Name</h1>
<p>Your account was created on @Model.CreatedAt.ToString("yyyy-MM-dd").</p>

Razor is especially strong when:

  • the output is markup-heavy
  • the team already uses ASP.NET
  • designers or developers need conditionals and loops in templates

For plain log messages or short strings, though, Razor is usually too heavy.

What to Avoid

A lot of older codebases build templates like this:

csharp
1string template = "Hello {name}, your total is {total}.";
2string result = template
3    .Replace("{name}", "Mark")
4    .Replace("{total}", "129.95");

This looks simple, but it scales badly:

  • placeholder names can collide unexpectedly
  • missing values are easy to miss
  • escaping rules are unclear
  • formatting becomes inconsistent

It is acceptable for one or two internal placeholders, but it is not a strong general templating strategy.

Choosing by Use Case

A practical decision table is:

  • use interpolation for code-authored strings
  • use string.Format for reusable resource templates with positional arguments
  • use Razor or Scriban for external, named, user-editable, or markup-rich templates

That keeps the solution proportional to the problem instead of defaulting either to over-engineering or to fragile string concatenation.

Common Pitfalls

  • Using a full template engine for tiny code-owned strings that string interpolation already handles cleanly.
  • Building user-editable or markup-heavy templates with ad hoc Replace chains.
  • Mixing formatting, localization, and escaping rules directly into manual replacement code.
  • Inventing a custom template language when established libraries already solve parsing and escaping.
  • Choosing a templating approach based only on familiarity instead of on who owns the template and how dynamic it is.

Summary

  • String interpolation is usually the best default for templates written in C# code.
  • 'string.Format still works well for positional resource-based templates.'
  • Named external templates are better served by a real engine such as Scriban or Razor.
  • Manual Replace chains are fragile beyond very small cases.
  • Pick the lightest approach that still matches the template's ownership and complexity.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.