Skip to content

[Everyday C#] - PR 11. String interpolation search split#53991

Draft
BillWagner wants to merge 9 commits into
dotnet:mainfrom
BillWagner:string-interpolation-search-split
Draft

[Everyday C#] - PR 11. String interpolation search split#53991
BillWagner wants to merge 9 commits into
dotnet:mainfrom
BillWagner:string-interpolation-search-split

Conversation

@BillWagner
Copy link
Copy Markdown
Member

@BillWagner BillWagner commented May 21, 2026

Fixes #53553

Phase D, PR 11 of the Everyday C# Fundamentals restructuring (issue #53553). Pull and revise three string articles into the new Fundamentals/Strings section, redistribute deep-cut content to a new Language Reference page, update TOC, and add redirects. Stage commits locally on the existing branch (no PR open).

Primary files to review:

Steps

Phase 1 — New snippet projects (parallel, independent)

  1. Create docs/csharp/fundamentals/strings/snippets/interpolation/interpolation.csprojnet10.0, OutputType=Exe, ImplicitUsings=enable, Nullable=enable (match null-safety convention).
  2. Create docs/csharp/fundamentals/strings/snippets/interpolation/Program.cs — port the snippets from docs/csharp/tutorials/snippets/StringInterpolation/Program.cs with these adjustments:
    • Use // <general>, // <format-string>, // <alignment>, // <alignment-and-format>, // <escapes>, // <conditional>, // <culture>, // <invariant> lowercase ids (match repo convention in recent how-to snippets).
    • Add new region // <newlines> — multi-line interpolation expression body (C# 11) with {} containing line break and embedded operators.
    • Add new region // <constant-interpolated>const string Greeting = $"Hello, {Audience}!"; with const string Audience = "world"; (C# 10).
    • Drop the older FormattableString examples (CultureSensitiveOld, InvariantCultureOld); keep only the modern string.Create form. Older form belongs in string-operations.md if needed (decide during writing — likely just dropped per Goal 9: don't tell readers their existing code is broken; older form is still in Language Reference).
    • Use file-scoped namespace, raw string literals where they tighten output examples, collection expressions where collections appear.
    • Trailing // => … comments on every output line.
  3. Create docs/csharp/fundamentals/strings/snippets/search/search.csproj — same config.
  4. Create docs/csharp/fundamentals/strings/snippets/search/Program.cs — port only everyday snippets from the existing SearchStrings.cs:
    • <contains>Contains / StartsWith / EndsWith with StringComparison.CurrentCultureIgnoreCase and StringComparison.Ordinal discussion in prose.
    • <index-of>IndexOf / LastIndexOf with the substring extraction example.
    • Drop the two regex regions (Snippet3, Snippet4); they move to string-operations.md.
    • Add <contains-char>Contains(char) overload (one-line, often-missed).
  5. Create docs/csharp/fundamentals/strings/snippets/split/split.csproj — same config.
  6. Create docs/csharp/fundamentals/strings/snippets/split/Program.cs — port from existing ParseStringsUsingSplit.cs:
    • Keep all eight existing examples; rename ids to <split-words>, <index-words>, <repeated-separators>, <multi-char>, <multi-char-gaps>, <string-separators>, <limit-count>, <trim-entries>.
    • Replace string[] arrays with collection expressions (["...", "..."]).
    • Drop the "Use AI to split a string" subsection — fails Filter A (universality) for an Everyday C# article.
  7. Create docs/csharp/language-reference/builtin-types/snippets/string-operations/string-operations.csproj — same config.
  8. Create docs/csharp/language-reference/builtin-types/snippets/string-operations/Program.cs — port the two regex regions from SearchStrings.cs (<regex-pattern>, <regex-validate>); add a brief <span-search> showing MemoryExtensions.IndexOf over ReadOnlySpan<char>.

Phase 2 — New Fundamentals articles (parallel within phase, depend on Phase 1)

  1. Create docs/csharp/fundamentals/strings/interpolation.md:

    • Frontmatter: title, description, ms.date: 05/21/2026, ms.topic: concept-article, ai-usage: ai-assisted.
    • Standard Fundamentals tip block (matches null-safety/index.md) routing newcomers to Get started, experienced devs to Language Reference.
    • Sections: Introduction → Format string → Alignment → Alignment + format → Escapes and braces → Conditional in expression → Multi-line interpolation expressions (C# 11)Constant interpolated strings (C# 10) → Culture-specific results.
    • Reference snippets via :::code language="csharp" source="snippets/interpolation/Program.cs" id="..."::: (use id not ID to match how-to convention).
    • Cross-link Language Reference interpolated string token and string-operations.md for advanced handler/perf content.
  2. Create docs/csharp/fundamentals/strings/search.md:

    • Same frontmatter pattern.
    • Sections: Lead with motivation → "Does a string contain text?" (Contains/StartsWith/EndsWith, including Contains(char)) → "Where does the text occur?" (IndexOf/LastIndexOf with substring extraction) → "Choosing the right comparison" (brief explanation of StringComparison ordinal vs. current-culture, recommend Ordinal for invariants and CurrentCultureIgnoreCase for user-facing searches, with justification per Goal 9).
    • Out-of-scope callout near top: regex pattern matching → link to string-operations.md; deeper culture-sensitive comparison → link to existing docs/standard/base-types/comparing-strings.md.
  3. Create docs/csharp/fundamentals/strings/split.md:

    • Same frontmatter pattern.
    • Sections: Split into words → Multiple separators (chars / strings) → Limit substring count → Remove empty entries → Trim entries.
    • Drop the AI-prompt subsection; replace with "When to reach for Regex.Split" pointer (one sentence, link to string-operations.md).

Phase 3 — Redistributed Language Reference page (depends on Phase 1)

  1. Create docs/csharp/language-reference/builtin-types/string-operations.md:
    • Frontmatter: title: "String operations: pattern matching, performance, and span-based search", ms.topic: reference, no ai-usage (Reference content), no F1/helpviewer keywords (those stay on reference-types.md).
    • Sections:
      • Find specific text using regular expressions — port the the/their example with Regex.IsMatch from current search-strings.md.
      • Validate strings against a pattern — port the telephone-number validation example.
      • string methods vs. regular expressions — keep the existing tip but expand into a paragraph with guidance: prefer string methods for known literals and prefixes; use regex for patterns or alternations.
      • Search using ReadOnlySpan<char> — show MemoryExtensions.IndexOf and explain when allocation avoidance matters (high-throughput parsers, hot paths). One short example.
      • Performance considerations — brief notes on StringComparison defaulting to current culture in older overloads and the cost of culture-sensitive comparison vs. Ordinal.
    • "See also" links to regular-expression-language-quick-reference.md, best-practices-strings.md, fundamentals/strings/search.md, fundamentals/strings/split.md.

Phase 4 — TOC updates (depend on Phases 2 & 3)

  1. Modify docs/csharp/toc.yml:

    • Remove lines 336–337 ("Split strings into substrings" how-to entry) and lines 340–341 ("Search strings" how-to entry) under the How-to C# articles node.
    • Add a new Strings node in the Fundamentals section, inserted between Null safety and Object-oriented programming (after line 84). Three entries — Interpolationfundamentals/strings/interpolation.md, Search stringsfundamentals/strings/search.md, Split strings into substringsfundamentals/strings/split.md. Per Decision (c), do not pre-add PR 10 entries; whoever merges last fixes ordering.
  2. Modify docs/csharp/language-reference/toc.yml:

    • Add a String operations entry under Reference types (around line 60, near Built-in reference types) pointing at ./builtin-types/string-operations.md.

Phase 5 — Redirects + cleanup (depends on Phase 4)

  1. Modify .openpublishing.redirection.csharp.json:

    • Add /docs/csharp/how-to/search-strings.md/dotnet/csharp/fundamentals/strings/search.
    • Add /docs/csharp/how-to/parse-strings-using-split.md/dotnet/csharp/fundamentals/strings/split.
    • Insert in alphabetical order (the file is sorted by source_path_from_root).
  2. Delete docs/csharp/how-to/search-strings.md and docs/csharp/how-to/parse-strings-using-split.md.

  3. Delete docs/csharp/how-to/snippets/strings/SearchStrings.cs and docs/csharp/how-to/snippets/strings/ParseStringsUsingSplit.cs.

  4. Modify docs/csharp/how-to/snippets/strings/Program.cs — drop the ParseStringsUsingSplit.Examples() and SearchStrings.Examples() calls and their banner lines so the project still builds.

Phase 6 — Verification

  1. dotnet build each new snippet project (interpolation, search, split, string-operations) and the modified how-to/snippets/strings. All must build clean and dotnet run must produce sane output. Spot-check 2–3 snippet outputs match the trailing // => … comments per Goal 4.
  2. Run git status / git diff --stat to confirm the file count is in the ~10-file range expected for PR 11 (snippets + 3 articles + 1 LR article = ~9 files; plus toc/redirects/deletes).
  3. Manually verify each article passes the concept template structure and that none carries F1/helpviewer keywords (per copilot-instructions.md).
  4. Validate Markdown link targets in the new articles (cross-references to language-reference/tokens/interpolated.md, string-operations.md, etc.) using the existing markdown-links-verifier-config.json if available, or by visual inspection.
  5. Stage commits locally — do not push or open a PR. Suggested commits: (1) snippets, (2) new Fundamentals articles + LR string-operations, (3) toc.yml + language-reference toc.yml, (4) redirects + deletes. (Commit grouping is advisory; user can resequence.)

Relevant files

  • docs/csharp/tutorials/string-interpolation.md — source for interpolation.md. Stays in place per user's call (PR 12 moves it). Snippet project at tutorials/snippets/StringInterpolation/Program.cs is the template; copy and modernize.
  • docs/csharp/how-to/search-strings.md — source for search.md; delete after pull. Has a typo on line 62 (./snippets/\strings/...) that should not be carried forward.
  • docs/csharp/how-to/parse-strings-using-split.md — source for split.md; delete after pull.
  • docs/csharp/how-to/snippets/strings/ — shared project; only delete the two relevant .cs files and adjust Program.cs.
  • docs/csharp/fundamentals/null-safety/nullable-value-types.md and docs/csharp/fundamentals/null-safety/index.md — style/structure templates from PR 8 (frontmatter, tip block, snippet reference style).
  • docs/csharp/fundamentals/null-safety/snippets/nullable-value-types/nullable-value-types.csproj — snippet project template (net10.0, exe).
  • docs/csharp/toc.yml — Fundamentals section ends at line 84 (null-operators); how-to entries to remove are at 336–337 and 340–341.
  • docs/csharp/language-reference/toc.yml — Reference types group is around lines 52–66.
  • .openpublishing.redirection.csharp.json — sorted alphabetically by source_path_from_root; redirects use /dotnet/... URL form (no .md).
  • .github/copilot-instructions.mdai-usage: ai-assisted required on AI-generated content; no F1/helpviewer keywords on Fundamentals articles; snippet block format :::code language="..." source="..." id="...":::.
  • .github/instructions/Markdown.WritingStyle.instructions.md — apply when writing the three new articles.

Internal previews

📄 File 🔗 Preview link
docs/csharp/fundamentals/strings/interpolation.md String interpolation in C#
docs/csharp/fundamentals/strings/search.md "Search strings in C#"
docs/csharp/fundamentals/strings/split.md Split strings into substrings in C#
docs/csharp/how-to/index.md docs/csharp/how-to/index
docs/csharp/how-to/modify-string-contents.md How to modify string contents in C#
docs/csharp/language-reference/builtin-types/string-operations.md String operations: pattern matching, performance, and span-based search
docs/csharp/language-reference/toc.yml docs/csharp/language-reference/toc
docs/csharp/programming-guide/strings/index.md Strings and string literals
docs/csharp/toc.yml Taken from https://github.com/dotnet/roslyn/wiki/Samples-and-Walkthroughs
docs/standard/base-types/divide-up-strings.md Separate strings into substrings

Build the projects for this PR.
Build the main articles for this PR.
Move the advanced material into an appropriate language reference article.

This information doesn't fit the fundamentals goals, but is important for more advanced developers.
Remove (now) obsolete articles.
Add necessary redirects.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR continues the Everyday C# Fundamentals restructuring by moving string-focused how-to content into the new Fundamentals > Strings area, adding a complementary language reference page for advanced string operations, and wiring everything up via TOC updates and redirects.

Changes:

  • Adds new Fundamentals articles for string interpolation, searching, and splitting, backed by new net10.0 snippet projects.
  • Introduces a new language reference page for regex usage, span-based search, and StringComparison guidance, plus a new snippet project.
  • Updates C# TOCs, adds redirects, and removes superseded how-to articles/snippets (and updates the remaining how-to snippets driver).

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
docs/csharp/toc.yml Adds a new Fundamentals Strings node and removes old string how-to entries.
docs/csharp/language-reference/toc.yml Adds a String operations entry under reference types.
docs/csharp/language-reference/builtin-types/string-operations.md New language reference article consolidating regex, span search, and comparison/perf guidance.
docs/csharp/language-reference/builtin-types/snippets/string-operations/string-operations.csproj New snippet project for the language reference page.
docs/csharp/language-reference/builtin-types/snippets/string-operations/Program.cs Regex and span-search snippet regions for the new language reference page.
docs/csharp/fundamentals/strings/interpolation.md New Fundamentals article for interpolation concepts and common patterns.
docs/csharp/fundamentals/strings/search.md New Fundamentals article for searching strings and choosing comparisons.
docs/csharp/fundamentals/strings/split.md New Fundamentals article for splitting strings with String.Split.
docs/csharp/fundamentals/strings/snippets/interpolation/interpolation.csproj New snippet project for interpolation article examples.
docs/csharp/fundamentals/strings/snippets/interpolation/Program.cs New interpolation snippet regions, including multi-line and constant interpolation examples.
docs/csharp/fundamentals/strings/snippets/search/search.csproj New snippet project for search article examples.
docs/csharp/fundamentals/strings/snippets/search/Program.cs New search snippet regions (Contains, Contains(char), IndexOf/LastIndexOf).
docs/csharp/fundamentals/strings/snippets/split/split.csproj New snippet project for split article examples.
docs/csharp/fundamentals/strings/snippets/split/Program.cs New split snippet regions covering common Split overload patterns.
.openpublishing.redirection.csharp.json Adds redirects from removed how-to pages to new Fundamentals pages.
docs/csharp/how-to/snippets/strings/Program.cs Removes calls to deleted string search/split examples so the project still builds.
docs/csharp/how-to/snippets/strings/SearchStrings.cs Deletes the old how-to search snippet source (migrated).
docs/csharp/how-to/snippets/strings/ParseStringsUsingSplit.cs Deletes the old how-to split snippet source (migrated).
docs/csharp/how-to/search-strings.md Deletes the old how-to article (replaced by Fundamentals + language reference content).
docs/csharp/how-to/parse-strings-using-split.md Deletes the old how-to article (replaced by Fundamentals content).
Comments suppressed due to low confidence (2)

docs/csharp/language-reference/builtin-types/string-operations.md:10

  • The xref <xref:System.ReadOnlySpan%601> encodes the backtick as %60. Repo guidance in .github/copilot-instructions.md says not to encode backticks in API doc IDs; use an unencoded doc ID (or a closed generic like System.ReadOnlySpan{System.Char}) instead.

This article covers string operations that go beyond the everyday `Contains`/`IndexOf`/`Split` methods covered in the Fundamentals [Search strings](../../fundamentals/strings/search.md) and [Split strings into substrings](../../fundamentals/strings/split.md) articles. It focuses on three areas: regular-expression pattern matching, allocation-free search over <xref:System.ReadOnlySpan%601>, and performance considerations for `string` comparison.

docs/csharp/fundamentals/strings/search.md:30

  • This sentence says Contains/StartsWith/EndsWith “default to case-sensitive, ordinal comparison”, but StartsWith(string)/EndsWith(string) default to current-culture semantics unless you pass StringComparison. Consider updating the sentence (and potentially the snippet) to encourage using the StringComparison overloads when you care about culture/ordinal behavior.
Use `Contains`, `StartsWith`, or `EndsWith` to test for the presence of a substring:

:::code language="csharp" source="snippets/search/Program.cs" id="contains":::

These methods default to **case-sensitive, ordinal** comparison. To accept user input or to ignore case for display text, pass a <xref:System.StringComparison> value such as <xref:System.StringComparison.CurrentCultureIgnoreCase?displayProperty=nameWithType> or <xref:System.StringComparison.OrdinalIgnoreCase?displayProperty=nameWithType>.

Comment thread docs/csharp/language-reference/builtin-types/string-operations.md
Comment thread docs/csharp/language-reference/builtin-types/string-operations.md
Comment thread docs/csharp/fundamentals/strings/search.md
Comment thread docs/csharp/fundamentals/strings/interpolation.md Outdated
Comment thread docs/csharp/fundamentals/strings/snippets/interpolation/Program.cs
BillWagner and others added 4 commits May 21, 2026 10:39
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Review the major changes and edit / content review.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Everyday C#] - Phase D, PR 11: Strings: interpolation + search + split

2 participants