String クラス

string str1 = "abc";                                    // "abc"
String str2 = new String(new char[] { 'a', 'b', 'c' }); // "abc"

Type type1 = str1.GetType(); // System.String
Type type2 = str2.GetType(); // System.String

C#においてはstringが、System.Stringのエイリアスとなっています。どちらでも使用可能ですが、System.Stringを用いると「名前を簡略化できます」としてIDE0001で警告されます。文字列と System.String - 文字列 - C# プログラミング ガイド | Microsoft Learn

既定値はnullです。

default(string) // null

コンストラクタ

多数のオーバーロードがあり、さまざまな型が許容されます。これらのコンストラクタの使い分けは、Which method do I call? - String Constructor (System) | Microsoft Learnに解説があります。

コンストラクタ 受け入れる型 処理する文字範囲 備考
String(Char, Int32) Unicode文字 (UTF-16) 全体 同一文字が連続した文字列を生成できる
String(Char*) Unicode文字配列を指すポインタ 全体  
String(Char*, Int32, Int32) 指定範囲  
String(Char[]) Unicode文字配列 全体 String - string.cs
String(Char[], Int32, Int32) 指定範囲  
String(SByte*) 8ビット符号付き整数配列を指すポインタ 全体  
String(SByte*, Int32, Int32) 指定範囲  
String(SByte*, Int32, Int32, Encoding) 処理する文字のエンコーディングを指定できる
コンストラクター - String クラス (System) | MSDN

CharとSByte以外ではコンストラクタを用いることはなく、

string str = "ABC";

のように文字列リテラルから生成できます。

charからstringへの変換

単一のcharからは、次のようにstringを作成できます。c# - How do I convert a single char to a string? - Stack Overflow

char ch = 'a';
string str1 = new string(ch, 1);
string str2 = new string(new[] { ch });
string str3 = ch.ToString();

このうちChar.ToString()は、new String(Char, 1);とするのに等しいです。ToString - char.cs

文字数

LengthプロパティはCharオブジェクトの数を返すため、Unicode文字の数と一致しないことがあります。たとえばサロゲートペアは2つのCharで表現されるため、1文字でも長さは2となります。

char[] chars = { '\uD83D', '\uDE00' };
string str = new String(chars); // "😀"
int len = str.Length; // 2

バイト数

Encoding.GetByteCount()で取得できます。Encoding.GetByteCount メソッド (System.Text) | Microsoft Learn

文字列の比較

等値

2つの文字列が等しいかどうかは、等値演算子で判断できます。

public static bool operator ==(
    string a,
    string b
)
String.Equality 演算子 (String, String) (System) | MSDN

この演算子はEquals(String, String)の呼び出しと等しく、StringComparison.Ordinalで比較されます。

string str1 = "abc";
bool r1 = str1 == "A";   // false
bool r2 = str1 == "ABC"; // false
bool r3 = str1 == "abc"; // true

柔軟な比較

等値演算子では空文字列とnullは等しくないと判定されますが、これを等しいと判定させるには、null合体演算子で空文字列に統一した上で比較します。c# - String Compare where null and empty are equal - Stack Overflow

Func<string, string, bool> comp = (s1, s2) =>
{
    return (s1 ?? string.Empty) == (s2 ?? string.Empty);
};

bool r0 = "" == null; // false

bool r1 = comp("A", "A");   // true
bool r2 = comp("A", "B");   // false
bool r3 = comp("", "");     // true
bool r4 = comp(null, null); // true
bool r5 = comp("", null);   // true
bool r6 = comp(null, "");   // true

String.Equals()

メソッド 比較元 比較方法
Equals(String) この文字列 標準 (StringComparison.Ordinal)
Equals(String, StringComparison) この文字列 指定の規則
Equals(String, String) 指定の文字列 標準 (StringComparison.Ordinal)
Equals(String, String, StringComparison) 指定の文字列 指定の規則
String.Equals メソッド (System) | MSDN

文字列の比較でStringComparisonを指定しないと、CA1307で警告されます。

StringComparison列挙型
列挙子 比較方法 並べ替え規則 大文字/小文字の区別
Ordinal 序数 (バイナリ) ※1 カルチャに非依存 する
OrdinalIgnoreCase しない
CurrentCulture 現在のカルチャ カルチャに依存 する
CurrentCultureIgnoreCase しない
InvariantCulture 不変のカルチャ する
InvariantCultureIgnoreCase しない
メンバー - StringComparison 列挙型 (System) | MSDN

※1 序数並べ替え規則 (ordinal sort rules) では、文字列のChar数値 (Unicodeコードポイント) に基づいて比較されます。これは高速ですが、カルチャは区別されません。注釈 - StringComparison 列挙型 (System) | Microsoft Learn

相対位置

2つの文字列を並べ替える場合の、前後関係を取得できます。

public static int Compare(
    string strA,
    string strB
)
String.Compare メソッド (String, String) (System) | MSDN String.Compare メソッド (System) | MSDN
int r1 = String.Compare("a", "a"); //  0
int r2 = String.Compare("a", "b"); // -1
int r3 = String.Compare("b", "a"); //  1

int r4 = String.Compare("a", "aa"); // -1

int r6 = String.Compare("a", "");   //  1
int r7 = String.Compare("a", null); //  1

半角/全角を区別しないなど、より詳細な条件で比較するにはCompareOptionsを指定します。

public static int Compare (
    string strA,
    string strB,
    System.Globalization.CultureInfo culture,
    System.Globalization.CompareOptions options
    );
Compare(String, String, CultureInfo, CompareOptions) - String.Compare メソッド (System) | Microsoft Learn

String.CompareOrdinal()

Compare()は並べ替え順で比較しますが、CompareOrdinal()はコードポイントで比較できます。

public static int CompareOrdinal (
    string strA,
    string strB
    );
CompareOrdinal(String, String) - String.CompareOrdinal メソッド (System) | Microsoft Learn

文字列の整形

書式

指定の書式によって整形された文字列を取得できます。

public static string Format(
    string format, // 書式指定文字列
    object arg0    // 整形するオブジェクト
)
Format(String, Object) - String.Format メソッド (System) | Microsoft Learn
string str = String.Format("{0}:{1}", "ABC", 10); // "ABC:10"
string s0 = String.Format("{0}"         , "A");           // "A"
string s1 = String.Format("{0}{1}"      , "A", "B");      // "AB"
string s2 = String.Format("{0}{1}{2}"   , "A", "B", "C"); // "ABC"
string s3 = String.Format("{0}{1}{2}{0}", "A", "B", "C"); // "ABCA"
string s4 = String.Format("{0}{1}{2}{3}", "A", "B", "C"); // FormatException「インデックス (0 ベース) は 0 以上で、引数リストのサイズよりも小さくなければなりません。」

カルチャに依存する内容ならば、IFormatProviderを引数に取るオーバーロードでそれを指定します。

public static string Format (
    IFormatProvider provider, // カルチャ特有の書式情報またはカスタム書式を提供するオブジェクト
    string format,            // 書式指定文字列
    object arg0               // 整形するオブジェクト
    );
Format(IFormatProvider, String, Object) - String.Format メソッド (System) | Microsoft Learn
string s1 = String.Format(CultureInfo.CreateSpecificCulture("ja"), "{0}", 1.5); // "1.5"
string s2 = String.Format(CultureInfo.CreateSpecificCulture("fr"), "{0}", 1.5); // "1,5"

書式の変更

カルチャの情報を修正することで、書式を変更できます。

NumberFormatInfo formatInfo = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone();
formatInfo.CurrencySymbol = "A";
formatInfo.CurrencyPositivePattern = 3;

string s1 = String.Format("{0:C}", 10);             // "¥10"
string s2 = String.Format(formatInfo, "{0:C}", 10); // "10 A"

カスタム書式

IFormatProviderとICustomFormatterインターフェイスを実装するクラスを作成し、それをString.Format()の引数に与えることで書式を任意に指定できます。

たとえば次のように書式設定用のクラスを用意すると、

public class MyFormat : IFormatProvider, ICustomFormatter
{
    public object GetFormat(Type formatType)
    {
        // カスタム書式のオブジェクトが要求されているかどうかを判定する
        return formatType == typeof(ICustomFormatter) ? this : null;
    }

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        // argの書式情報を提供するformatProviderは、一般的にこのインスタンスに等しい
        if (!object.ReferenceEquals(this, formatProvider))
        {
            return null; // formatの文字列を返すのと同じ
        }

        if (arg is int)
        {
            int val = (int)arg;
            switch (format)
            {
                case "A":
                    return (val * 2).ToString();
                case "B":
                    return (val * 3).ToString();
            }
        }

        return arg.ToString();
    }
}

次のように利用できます。

string str1 = String.Format(new MyFormat(), "{0:A}", 2); // "4"
string str2 = String.Format(new MyFormat(), "{0:B}", 2); // "6"
string str3 = String.Format(new MyFormat(), "{0}", 2);   // "2"
例 - 方法: カスタム数値書式プロバイダーを定義して使用する | Microsoft Learn
複数形

ICustomFormatter.Format()の実装によっては、単語の単数と複数形のように、引数によって異なる結果を返すこともできます。

public string Format(string format, object arg, IFormatProvider formatProvider)
{
    string[] words = format.Split(';');
    if (words.Length == 2 && arg is int)
    {
        int number = (int)arg;
        string word = words[number == 1 ? 0 : 1];

        return $"{number} {word}";
    }
    return arg.ToString();
}
c# - Clever way to append 's' for plural form in .Net (syntactic sugar) - Stack Overflow Is negative one plural? - Meta Stack Exchange
string str1 = String.Format(new MyFormat(), "{0:item;items}", 1); // "1 item"
string str2 = String.Format(new MyFormat(), "{0:item;items}", 2); // "2 items"

単語から、その単数や複数形を得たいならばPluralizationServiceを用います。

削除

開始位置から末尾、または指定文字数だけ削除された文字列を得られます。

public string Remove(
    int startIndex, // 削除を開始する位置
    int count       // 削除する文字数
)
String.Remove メソッド (Int32, Int32) (System) | MSDN
"ABCD".Remove(1); // "A"
"ABCD".Remove(2); // "AB"
"ABCD".Remove(4); // ArgumentOutOfRangeException「startIndex には文字列の長さより小さい値を指定してください。」

"ABCD".Remove(1,2); // "AD"

刈り込み

先頭と末尾から、Char.IsWhiteSpace()で空白とみなされる文字を削除できます。

public string Trim()
Trim() - String.Trim メソッド (System) | Microsoft Learn
" ABC ".Trim(); // "ABC"

.NET Framework 4以降、引数なしのこのメソッドではすべてのUnicode空白文字が除去されます。対象となる文字は.NET 3.5 SP1の前後で変更されており、

  • .NET 4以降、対象から除外
    • ZERO WIDTH SPACE (U+200B)
    • ZERO WIDTH NO-BREAK SPACE (U+FEFF)
  • .NET 4以降、対象に追加
    • MONGOLIAN VOWEL SEPARATOR (U+180E)
    • NARROW NO-BREAK SPACE (U+202F)
    • MEDIUM MATHEMATICAL SPACE (U+205F)

となっています。Notes to Callers - String.Trim Method (System) | Microsoft Learn

引数をとるメソッドでは、除去する文字を指定できます。

public string Trim(params char[] trimChars)
Trim(Char[]) - String.Trim メソッド (System) | Microsoft Learn
" ABC ".Trim(' ', 'A'); // "BC"

これを利用すれば、.NET 4以降に対象から除外された文字を除去できます。

str.Trim('\u200B', '\uFEFF');

このメソッドの内部では、先頭と末尾から空白ではない文字が順に探され、それが見つかった位置の文字列が抽出されて返されます。Trim - string.cs

先頭か末尾のいずれかのみ

Trim()では先頭と末尾から除去されますが、TrimStart()とTrimEnd()ではそのいずれかだけを対象にできます。これらのメソッドでは引数を省略するかnullを指定すると、空白文字が除去の対象となります。

public string TrimStart(params char[] trimChars)
public string TrimEnd(params char[] trimChars)

大文字/小文字の変換

小文字への変換

public string ToLower ();
ToLower() - String.ToLower メソッド (System) | Microsoft Learn

変換方法はカルチャに依存するため、それが問題となるならば引数でCultureInfoを指定します。またはカルチャに依存しない結果が得られる、ToLowerInvariant()を用います。小文字を大文字に、大文字を小文字に変換する - .NET Tips (VB.NET,C#...)

ただしToLowerInvariant()を用いると「文字列を大文字に標準化します」としてCA1308で警告されるため、正規化するのが目的ならばToUpperInvariant()で大文字へ変換します。これは大文字より小文字として定義された文字が少ないため、異なるロケール間で文字を変換したときに元に戻すラウンド トリップ (round trip) ができない恐れがあるためです。

Appendix:Variations of "a" - Wiktionary, the free dictionary

大文字への変換

public string ToUpper ();
ToUpper() - String.ToUpper メソッド (System) | Microsoft Learn

注意点は、小文字への変換と同様です。

文字列の連結

加算演算子

加算演算子 (+) で文字列同士を連結、加算代入演算子 (+=) で文字列に対して連結できます。

string str = "AA" + "BB"; // "AABB"
str += 10;                // "AABB10"

多数の文字列を連結するならばStringBuilderを用います。

加算演算子による連結は、コンパイラによってString.Concat()に翻訳されます。Remarks - String.Concat Method (System) | Microsoft Learn

String.Concat()

複数のオブジェクトまたはStringを、文字列として連結できます。

public static string Concat(
    object arg0,
    object arg1
)
String.Concat メソッド (Object, Object) (System) | MSDN String.Concat メソッド (System) | MSDN
String.Concat("ABC", true);    // "ABCTrue"
String.Concat(10, 'a');        // "10a"
String.Concat(1.5, null, 'B'); // "1.5B"

可変引数をとるオーバーロードもあり、任意の数のオブジェクトを連結できます。

public static string Concat(
    params object[] args
)
String.Concat メソッド (Object[]) (System) | MSDN

ただし配列を渡した場合、それが1つならばこのメソッドで要素ごとに連結されますが、複数渡すとそれぞれの文字列形式で連結されます。

String.Concat(     new int[] { 1, 2, 3 }); // "123"
String.Concat("A", new int[] { 1, 2, 3 }); // "ASystem.Int32[]"

内部ではObject.ToString()で文字列を得るため、結果はカルチャ依存となります。Concat - string.cs

DateTime date = new DateTime(2000, 1, 2);
string s = String.Concat(date, "A"); // "2000/01/02 0:00:00A"

String.Join()

文字列配列を、指定の区切り文字で連結できます。これとは逆に、指定の区切り文字で分割するならばString.Split()を用います。

public static string Join(
    string separator,
    params string[] value
)
String.Join メソッド (String, String[]) (System) | MSDN
String.Join(",", new[] { "a", "b", "c", null, "" }); // "a,b,c,,"
String.Join(",", new string[] { });                // ""
String.Join("x", 1);    // "1"
String.Join("x", 1, 2); // "1x2"

引数で開始位置と数を指定することで、連結する範囲を制限できます。

public static string Join(
    string separator,
    string[] value,
    int startIndex, // 使用する最初の要素
    int count       // 使用する要素の数
)
String.Join メソッド (String, String[], Int32, Int32) (System) | MSDN
string[] str = new string[] { "a", "b", "c" };
string r1 = String.Join(",", str, 0, 2); // "a,b"
string r2 = String.Join(",", str, 1, 2); // "b,c"

string r3 = String.Join(",", str, 3, 1); // System.ArgumentOutOfRangeException
string r4 = String.Join(",", str, 1, 3); // System.ArgumentOutOfRangeException

このメソッドにはIEnumerable<T>を引数にとるオーバーロードもあるため、列挙可能なコレクションならば文字列として連結できます。

List<int> array = new List<int> { 1, 2, 3 };
string r = String.Join("-", array); // "1-2-3"

そのときそのオブジェクトのToString()が返す文字列が期待するものでなければ、Enumerable.Select()で変更します。

Point[] p = new[] { new Point(1, 2), new Point(3, 4) };
string r1 = string.Join(", ", p);                  // "{X=1,Y=2}, {X=3,Y=4}"
string r2 = string.Join(", ", p.Select(a => a.X)); // "1, 3"

文字列の分割

String.Split()

public string[] Split(
    params char[] separator
)
Split(Char[]) - String.Split メソッド (System) | Microsoft Learn

separatorがnullか空の配列の場合には、空白文字が区切り文字として用いられます。ここで空白文字はUnicode standardで定義されている文字で、Char.IsWhiteSpace()がtrueを返す文字です。 Split(Char[]) - String.Split Method (System) | Microsoft Learn MakeSeparatorList - string.cs

string text = "a b,c";
string[] r1 = text.Split(null);           // "a", "b,c"
string[] r2 = text.Split(new char[] { }); // "a", "b,c"

separatorに単一の文字を渡すと、コンパイラによって単一要素の文字配列と解釈されます。String. Split (Char []) とコンパイラのオーバーロードの解決 - String.Split Method (System) | Microsoft Learn

string text = "a,b,c";
string[] r1 = text.Split(new char[] { ',' });
string[] r2 = text.Split(','); // OK

string[] r3 = text.Split(new string[] { "," }, StringSplitOptions.None);
string[] r4 = text.Split(",", StringSplitOptions.None); // error CS1503: 引数 1: は 'string' から 'char' へ変換することはできません。

optionsでStringSplitOptions.RemoveEmptyEntriesを指定すると、空文字列の要素を除外できます。

[System.Runtime.InteropServices.ComVisible(false)]
public string[] Split (string[] separator, StringSplitOptions options);
Split(String[], StringSplitOptions) - String.Split Method (System) | Microsoft Learn
string[] r1 = "a,b,,c,".Split(new char[] { ',' }, StringSplitOptions.None);               // "a","b","","c",""
string[] r2 = "a,b,,c,".Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); // "a","b","c"

しかし空白文字だけで構成される要素は残ります。これは.NET 5以降ならば、TrimEntriesも同時に指定することで除外できます。

string[] r3 = "a,b, ,c, ".Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); // "a","b"," ","c"," "

separatorに複数の文字列が含まれるとき、それらは大文字/小文字を区別した順に並べ替えられた上で処理されます。Comparison details - String.Split Method (System) | Microsoft Learn

string[] r1 = "abcdef".Split(new[] { "ef", "bcde" }, StringSplitOptions.None); // "a", "f"
string[] r2 = "abcdef".Split(new[] { "bcde", "ef" }, StringSplitOptions.None); // "a", "f"

string[] r3 = "abcdef".Split(new[] { "bcd", "bc" }, StringSplitOptions.None); // "a", "def"
string[] r4 = "abcdef".Split(new[] { "bc", "bcd" }, StringSplitOptions.None); // "a", "ef"

空文字列を分割すると、空文字列が返されます。

string[] r1 = "".Split(null); // ""

第2引数で数値を指定すると、分割する最大数を制限できます。

string text = "a b c";
string[] r1 = text.Split(null, 1); // "a b c"
string[] r2 = text.Split(null, 2); // "a", "b c"
string[] r3 = text.Split(null, 3); // "a", "b", "c"
string[] r4 = text.Split(null, 4); // "a", "b", "c"

文字列の抽出

public string Substring (
    int startIndex,
    int length
    );
Substring(Int32, Int32) - String.Substring Method (System) | Microsoft Learn

startIndexまたはlengthが0未満のときは、ArgumentOutOfRangeExceptionが投げられます。

string str = "012345";

string s0 = str.Substring(2);     // "2345"
string s1 = str.Substring(2, 3);  // "234"
string s2 = str.Substring(2, 10); // ArgumentOutOfRangeException

これとは逆に、指定範囲を除去した文字列を得たいならば、Remove()を呼びます。

"0123".Substring(2);    // "23"
"0123".Substring(0, 2); // "01"

"0123".Remove(2);       // "01"
"0123".Remove(0, 2);    // "23"

インデクサ

指定位置の文字を得られます。

public char this[int index] { get; }
String.Chars プロパティ (Int32) (System) | MSDN
string str = "ABC";

char c0 = str[0]; // 'A'
char c1 = str[1]; // 'B'
char c2 = str[2]; // 'C'
char c3 = str[3]; // IndexOutOfRangeException「インデックスが配列の境界外です。」

文字列の検索

戻り値の型 メソッド 機能
bool Contains() 指定文字列が含まれているかどうか
bool StartsWith() 先頭が、指定文字列と一致するかどうか
bool EndsWith() 末尾が、指定文字列と一致するかどうか
int IndexOf() 指定文字が、最初に見つかった位置を返す
int LastIndexOf() 指定文字が、最後に見つかった位置を返す
int IndexOfAny() 指定文字のいずれかが、最初に見つかった位置を返す
int LastIndexOfAny() 指定文字のいずれかが、最後に見つかった位置を返す
方法 : String のメソッドを使用して文字列を検索する (C# プログラミング ガイド) | MSDN

高度な条件で検索するには、正規表現のRegex.Match()を用います。

文字が指定位置にあるか確認するだけならば、インデクサで判定できます。

string str = "abc";
bool r = (str[0] == 'a'); // true

Contains()

public bool Contains (string value);
Contains(String) - String.Contains メソッド (System) | Microsoft Learn

.NET Frameworkには引数がcharであったりStringComparisonを指定するオーバーロードが用意されていないため、これらが必要ならばIndexOf()を用います。

StartsWith()

public bool StartsWith (string value);
StartsWith(String) - String.StartsWith メソッド (System) | Microsoft Learn
string str = "ABC";

bool r1 = str.StartsWith("AB");   // true
bool r2 = str.StartsWith("ABC");  // true
bool r3 = str.StartsWith("ABCD"); // false

StringComparisonを指定しない形式では、現在のカルチャで大文字/小文字を区別する単語検索 (word search) で比較されます。

valueが文字列ではなく文字ならば、インデクサで1文字目を読み取ることでも判定できます。ただしその場合は空文字列ではないことを確認しないと、IndexOutOfRangeExceptionとなる恐れがあります。

string str = "ABC";

bool r1 = str.StartsWith("A"); // true
bool r2 = str[0] == 'A';       // true

IndexOf()

指定文字が最初に見つかった位置を得られます。見つからなかった場合は、-1が返されます。

メソッド 検索対象 検索の開始位置 検索の終了位置 文字の比較方法
IndexOf(Char) 文字 最初 末尾 序数検索 (ordinal search)。カルチャ非依存
IndexOf(Char, Int32) 指定位置 末尾
IndexOf(Char, Int32, Int32) 指定位置 開始位置 + 指定文字数
IndexOf(String) 文字列 最初 末尾 単語検索 (word search)。現在のカルチャで大文字/小文字を区別
IndexOf(String, Int32) 指定位置 末尾
IndexOf(String, Int32, Int32) 指定位置 開始位置 + 指定文字数
indexOf(String, StringComparison) 文字列 最初 末尾 指定方法
IndexOf(String, Int32, StringComparison) 指定位置 末尾
IndexOf(String, Int32, Int32, StringComparison) 指定位置 開始位置 + 指定文字数
オーバーロード - String.IndexOf メソッド (System) | Microsoft Learn

IndexOf(Char)とIndexOf(String)では既定の比較方法が異なるため、これらを置き換えると異なる結果が返されることがあります。これをIndexOf(String)でもカルチャ非依存とするには、IndexOf(value, StringComparison.Ordinal)とします。

string str = "oe";
str.IndexOf('œ'); // -1
str.IndexOf("œ"); // 0
str.IndexOf("œ", StringComparison.Ordinal); // -1

空文字列は0文字目に一致します。

string str = "012";
str.IndexOf(""); // 0
str.IndexOf(''); // error CS1011: 空の文字リテラルです。

サロゲートペアで表現される文字は2文字と数えられるため、直感とは異なる位置となります。

"あいう".IndexOf("い"); // 1
"😀いう".IndexOf("い"); // 2

半角/全角を区別しないなど、より詳細な条件で検索するにはCompareOptionsを指定できるCompareInfo.IndexOf()を用います。

文字列の置換

メソッド 機能
Replace(Char, Char) 指定文字をすべて別の文字へ置換し、置換された新しい文字列を返す
Replace(String, String) 指定文字列をすべて別の文字列へ置換し、置換された新しい文字列を返す
Remove(Int32, Int32) 指定位置から指定数の文字を空文字に置換 (削除) し、削除された新しい文字列を返す
方法: 文字列の内容を変更する - C# ガイド | Microsoft Learn
public string Replace(
    char oldChar,
    char newChar
)
Replace(Char, Char) - String.Replace メソッド (System) | Microsoft Learn

oldCharが見つからなかった場合は、現在の文字列がそのまま返されます。

"ABC ABC".Replace('B', 'x'); // "AxC AxC"

サロゲートペアで表現される文字も適切に置換できます。

"😀😁😂😁".Replace("😁", "あ"); // 😀あ😂あ

Replace()は一致したすべてを置換するため、これを一致した最初だけとするにはRegex.Replace()で置換する回数を指定するか、String.IndexOf()で一致部分を取得してString.Substring()で連結します。c# - How do I replace the *first instance* of a string in .NET? - Stack Overflow

高度な条件で置換するには、正規表現のRegex.Replace()を用います。

文字列の挿入

Insert()

指定位置に、指定の文字列が挿入された文字列を得られます。

public string Insert (
    int startIndex, // 挿入する位置
    string value    // 挿入する文字列
    );
String.Insert(Int32, String) メソッド (System) | Microsoft Learn
string str = "01234".Insert(2, "AB"); // "01AB234"

PadLeft()

指定の文字数になるように、指定の文字が詰め込められた文字列を得られます。

public string PadLeft (
    int totalWidth,
    char paddingChar
    );
PadLeft(Int32, Char) - String.PadLeft メソッド (System) | Microsoft Learn
string str1 = "AB".PadLeft(4, '0');  // "00AB"
string str2 = "AB".PadRight(4, '0'); // "AB00"

文字列の判定

メソッド 機能
IsNormalized() この文字列が、Unicode正規形C (Unicode normalization form C) であるかどうか
IsNormalized(NormalizationForm) この文字列が、指定されたUnicode正規形であるかどうか
IsNullOrEmpty(String) 指定された文字列がnullまたはEmpty文字列であるかどうか。これは次のコードに相当する IsNullOrEmpty - string.cs
return (s == null) || (s == String.Empty);
解説 - String.IsNullOrEmpty メソッド (String) (System) | MSDN

パフォーマンスが問題となるならば、このメソッドにより空文字を判定します。CA1820: 文字列の長さを使用して空の文字列をテストします | MSDN

IsNullOrWhiteSpace(String) 指定された文字列がnullまたは空であるか、空白文字だけで構成されているかどうか。これは次のコードに相当する IsNullOrWhiteSpace - string.cs
if (value == null) return true;

for(int i = 0; i < value.Length; i++) {
    if(!Char.IsWhiteSpace(value[i])) return false;
}

return true;
解説 - String.IsNullOrWhiteSpace メソッド (String) (System) | MSDN
Microsoft Learnから検索