最直接的方法是用 Array.Reverse() 反转字符数组:先 ToCharArray(),再 Array.Reverse() 原地反转,最后 new string() 构造新字符串;str.Reverse() 需配合 ToArray() 和 new string() 才能得到字符串,否则返回 IEnumerable。

用 Array.Reverse() 最直接,但要注意它只反转字符数组
字符串在 C# 中是不可变的,所以不能直接反转原字符串。常见错误是写 str.Reverse() 后忘了调用 ToArray() 和 new string(),结果得到的是 IEnumerable,不是字符串。Reverse() 是 LINQ 方法,返回延迟执行的序列,不转成数组就拼不出新字符串。
推荐做法:
- 用
str.ToCharArray()转数组 - 调用
Array.Reverse(charArray)原地反转 - 再用
new string(charArray)构造新字符串
示例:
string str = "hello"; char[] chars = str.ToCharArray(); Array.Reverse(chars); string reversed = new string(chars); // "olleh"
string.Concat(str.Reverse()) 看似简洁,但性能有代价
这行代码能跑通,但背后会创建多个中间对象:先生成 IEnumerable,再逐个枚举、装箱(对值类型 char 不明显,但逻辑上存在)、最后拼接。小字符串无所谓,循环里高频调用或处理长文本时,GC 压力会上升。
适用场景:
- 一次性、低频、可读性优先的脚本或调试
- 字符串很短(
不建议用于:
- 高频日志处理、协议解析等性能敏感路径
- Unity 或 AOT 编译环境(LINQ 可能被裁剪或引发反射问题)
Unicode 字符(如 emoji、组合符号)会被拆开反转
C# 的 char 是 UTF-16 code unit,不是 Unicode 字符(grapheme cluster)。像 ?(U+1F30D)占两个 char,??(family + ZWJ + tech)可能占 4–5 个。直接反转 char 数组会导致 emoji 显示异常或乱码。
正确做法是按 grapheme cluster 切分再反转:
- 用
StringInfo.GetTextElementEnumerator(str)获取真实字符单元 - 收集所有 text elements 到列表,再调用
Reverse() - 用
string.Concat()拼接
示例:
var enumerator = StringInfo.GetTextElementEnumerator("??abc");
var elements = new List<string>();
while (enumerator.MoveNext())
elements.Add(enumerator.GetTextElement());
string reversed = string.Concat(elements.AsEnumerable().Reverse());</string>
自定义扩展方法最稳妥,但别漏掉 null 和空字符串检查
封装成 string.ReverseGrapheme() 很实用,但线上出过 bug 的地方往往是边界条件。有人只处理了 null,忘了 string.Empty;也有人用了 Span 优化,却在 .NET Core 3.1 以下版本报 NotSupportedException。
写扩展方法时务必包含:
if (str == null) return null;if (str.Length == 0) return str;- 明确标注最低支持的 .NET 版本(如需
ReadOnlySpan)
复杂点不在反转逻辑本身,而在你是否清楚当前字符串里有没有代理对、ZWJ 序列、变音符号——这些不会报错,但反转后肉眼一看就错。











