C产品如何满足特定用户需求?
- 内容介绍
- 文章标签
- 相关推荐
本文共计794个文字,预计阅读时间需要4分钟。
只需字符串非空,即可使用以下代码安全地截掉末尾一个字符:
常见错误是忽略长度检查,导致 ArgumentOutOfRangeException:
string str = ""; string result = str.Substring(0, str.Length - 1); // 崩溃:Length - 1 = -1
- 务必先判断
str.Length > 0 - 如果原串可能为
null,还得加str?.Length > 0或用空合并str ?? "" -
Substring性能好,无分配开销(.NET 6+ 对短字符串有优化)
别用 TrimEnd 去“移除最后一位”
TrimEnd 的作用是**移除末尾所有匹配的字符**,不是“只移一个”。比如 "abc__".TrimEnd('_') 得到 "abc",但 "ab_c".TrimEnd('_') 还是 "ab_c" —— 因为末尾不是 '_'。
更危险的是,它会批量清除——"a___".TrimEnd('_') 变成 "a",完全不是“去一位”的语义。
- 如果你真想删掉末尾连续的下划线,且不确定有几个,
TrimEnd('_')才合适 - 但目标是“固定删最后一位”,它不可控、不直观、易误解
- 对 Unicode 组合字符(如带重音的字母)也无特殊处理,和
Substring一样按 UTF-16 码元计数
边界情况:空串、null、单字符串怎么处理
真实代码里这些不能靠运气避开。建议封装成可复用的小逻辑,而不是每次手写判断:
public static string RemoveLastChar(string s) => string.IsNullOrEmpty(s) ? s : s.Substring(0, s.Length - 1);
-
string.IsNullOrEmpty(s)同时覆盖null和空串,比单独判Length == 0更稳妥 - 单字符串(如
"a")进函数后返回空串"",符合直觉 - 如果业务要求“至少保留两位”,就得额外加条件,比如
s.Length > 1 ? ... : s
性能与可读性:为什么不用 Span<char></char> 或 ReadOnlySpan
在高频或底层场景(如解析器、网络包处理),确实可以用 s.AsSpan().Slice(0, Math.Max(0, s.Length - 1)).ToString() 避免新字符串分配。但绝大多数业务代码没必要:
-
Substring在 .NET Core 3.0+ 已对小字符串做内存优化,实测差异微乎其微 -
Span版本可读性差,还强制要求 .NET Core 2.1+,增加维护成本 - 真正该警惕的不是这行代码,而是反复拼接 + 截取造成的多轮分配——这时应考虑
StringBuilder或一次性解析
下划线只是个字符,不是特殊标记;删最后一位也不是格式化,而是确定性的索引操作。盯住 Length 和空检查,比琢磨 API 花样更管用。
本文共计794个文字,预计阅读时间需要4分钟。
只需字符串非空,即可使用以下代码安全地截掉末尾一个字符:
常见错误是忽略长度检查,导致 ArgumentOutOfRangeException:
string str = ""; string result = str.Substring(0, str.Length - 1); // 崩溃:Length - 1 = -1
- 务必先判断
str.Length > 0 - 如果原串可能为
null,还得加str?.Length > 0或用空合并str ?? "" -
Substring性能好,无分配开销(.NET 6+ 对短字符串有优化)
别用 TrimEnd 去“移除最后一位”
TrimEnd 的作用是**移除末尾所有匹配的字符**,不是“只移一个”。比如 "abc__".TrimEnd('_') 得到 "abc",但 "ab_c".TrimEnd('_') 还是 "ab_c" —— 因为末尾不是 '_'。
更危险的是,它会批量清除——"a___".TrimEnd('_') 变成 "a",完全不是“去一位”的语义。
- 如果你真想删掉末尾连续的下划线,且不确定有几个,
TrimEnd('_')才合适 - 但目标是“固定删最后一位”,它不可控、不直观、易误解
- 对 Unicode 组合字符(如带重音的字母)也无特殊处理,和
Substring一样按 UTF-16 码元计数
边界情况:空串、null、单字符串怎么处理
真实代码里这些不能靠运气避开。建议封装成可复用的小逻辑,而不是每次手写判断:
public static string RemoveLastChar(string s) => string.IsNullOrEmpty(s) ? s : s.Substring(0, s.Length - 1);
-
string.IsNullOrEmpty(s)同时覆盖null和空串,比单独判Length == 0更稳妥 - 单字符串(如
"a")进函数后返回空串"",符合直觉 - 如果业务要求“至少保留两位”,就得额外加条件,比如
s.Length > 1 ? ... : s
性能与可读性:为什么不用 Span<char></char> 或 ReadOnlySpan
在高频或底层场景(如解析器、网络包处理),确实可以用 s.AsSpan().Slice(0, Math.Max(0, s.Length - 1)).ToString() 避免新字符串分配。但绝大多数业务代码没必要:
-
Substring在 .NET Core 3.0+ 已对小字符串做内存优化,实测差异微乎其微 -
Span版本可读性差,还强制要求 .NET Core 2.1+,增加维护成本 - 真正该警惕的不是这行代码,而是反复拼接 + 截取造成的多轮分配——这时应考虑
StringBuilder或一次性解析
下划线只是个字符,不是特殊标记;删最后一位也不是格式化,而是确定性的索引操作。盯住 Length 和空检查,比琢磨 API 花样更管用。

