C# 试题 22:字符串与文本处理
0421 以下代码输出什么?
难度: 实战
string s = "abc";
s.Replace("b", "X");
Console.WriteLine(s);
- A.
aXc - B.
abc,Replace返回新字符串,原串不变 - C. 编译失败
- D. 运行抛
NullReferenceException
查看答案与解析
正确答案B
解析: Replace 的结果是返回值,原字符串不可变、不会被修改;丢弃返回值等于什么都没做。
关键点: 字符串处理方法的返回值必须接收,原引用永远指向旧内容。
0422 以下代码能否编译?
难度: 进阶
string s = "abc";
s[0] = 'X';
- A. 编译通过,输出
Xbc - B. 编译通过,输出
abc - C. 运行抛
NotSupportedException - D. 编译失败,
string的索引器是只读的,没有 setter
查看答案与解析
正确答案D
解析: string 的索引器只有 getter,赋值在编译期被拒绝;不可变性由类型系统强制,而不是运行期检查。
关键点: 要修改字符序列用 StringBuilder 或 char[],字符串本身不可变。
0423 以下代码输出什么?
难度: 进阶
string a = "he" + "llo";
string b = "hello";
Console.WriteLine(ReferenceEquals(a, b));
- A.
True,"he" + "llo"是编译期常量,折叠后与字面量驻留在同一实例 - B.
False - C. 编译失败
- D. 运行抛异常
查看答案与解析
正确答案A
解析: 两个字符串字面量的 + 在编译期折叠为 "hello",与同值字面量共享驻留实例,因此引用相同。
关键点: 只有编译期可知的字符串才会被折叠和驻留;运行期拼接结果不驻留。
0424 以下代码输出什么?
难度: 实战
string a = "hello";
string b = new string('h', 1) + "ello";
Console.WriteLine(a == b);
Console.WriteLine(ReferenceEquals(a, b));
- A.
False和False - B.
True和True - C.
True和False,==比较内容,运行期拼接结果不驻留 - D.
False和True
查看答案与解析
正确答案C
解析: string 的 == 是值比较(内容相同为 True);但运行期拼接产生的新对象不会自动加入驻留池,与字面量不是同一引用。
关键点: “内容相等”和“引用相同”是两回事,驻留只对字面量与显式 Intern 生效。
0425 以下代码输出什么?
难度: 进阶
object a = "hello";
object b = new string('h', 1) + "ello";
Console.WriteLine(a == b);
- A.
True,内容相同 - B.
False,两个object的==是引用比较 - C. 编译失败
- D. 运行抛异常
查看答案与解析
正确答案B
解析: 变量类型是 object 时,== 走引用比较而不是 string 的值比较;两个不同实例即使内容相同也不相等。
关键点: 类型决定运算符语义,object == 与 string == 行为不同。
0426 以下代码输出什么?
难度: 实战
var sb = new StringBuilder("abc");
string s = sb.ToString();
sb[0] = 'X';
sb.Append("def");
Console.WriteLine(s);
Console.WriteLine(sb);
- A.
Xbc和abc - B.
abc和abc - C.
Xbcdef和Xbcdef - D.
abc和Xbcdef
查看答案与解析
正确答案D
解析: ToString() 返回当前内容的快照,之后 StringBuilder 的修改不再影响已取出的字符串;sb[0] = 'X' 是合法的(StringBuilder 索引器可写)。
关键点: StringBuilder 可变、快照不可变,二者生命周期要分清。
0427 以下代码输出什么?
难度: 进阶
var sb = new StringBuilder();
Console.WriteLine(sb.Capacity);
- A.
16 - B.
0 - C.
4 - D. 编译失败
查看答案与解析
正确答案A
解析: 无参构造的 StringBuilder 默认容量是 16 个字符;Length 是 0 但 Capacity 已经预留。
关键点: Capacity 与 Length 是两个概念:容量是内部缓冲,长度是有效内容。
0428 以下代码输出什么?
难度: 实战
var sb = new StringBuilder(100);
sb.Append("abc");
sb.Clear();
Console.WriteLine(sb.Length + " " + sb.Capacity);
- A.
0 0 - B.
3 100 - C.
0 100,Clear只清内容,容量保留 - D.
3 0
查看答案与解析
正确答案C
解析: Clear() 把 Length 置 0,但内部缓冲区与容量不变;下次 Append 不会立刻重新分配。
关键点: 清空与释放缓冲是两回事,长生命周期对象可复用容量。
0429 以下代码输出什么?
难度: 进阶
const string name = "C#";
const string message = $"Hello, {name}!";
Console.WriteLine(message);
- A. 编译失败,插值字符串不能是常量
- B.
Hello, C#!,所有插值表达式都是常量字符串时,插值字符串本身是编译期常量 - C.
Hello, {name}! - D. 运行抛
FormatException
查看答案与解析
正确答案B
解析: 当插值表达式全部是常量字符串时,插值字符串可以作为 const(编译期求值);注意插值常量并非“任何类型都行”,非字符串常量洞会让 const 声明失败。
关键点: “插值字符串一定非常量”是过时认知,但常量条件严格限定在常量字符串洞。
0430 以下代码输出什么?
难度: 实战
string? s = null;
Console.WriteLine($"[{s}]");
Console.WriteLine(string.Format("[{0}]", s));
- A.
[null]和[null] - B.
[]和[null] - C.
[null]和[] - D.
[]和[],null 在插值/格式化中输出空串
查看答案与解析
正确答案D
解析: 插值表达式与 string.Format 对 null 都输出空字符串,不抛异常;$"{s}" 与 $"{s?.ToString()}" 等价。
关键点: “null 插值成 null 文本”是常见误解,实际是空串。
0431 以下代码输出什么?
难度: 实战
Console.WriteLine(string.IsNullOrEmpty(" \t "));
Console.WriteLine(string.IsNullOrWhiteSpace(" \t "));
- A.
False和True - B.
True和True - C.
False和False - D.
True和False
查看答案与解析
正确答案A
解析: IsNullOrEmpty 只认 null 与空串,含空白字符的字符串不是空;IsNullOrWhiteSpace 把空白字符也视为空。
关键点: 校验“空白输入”要用 IsNullOrWhiteSpace,两个方法不等价。
0432 以下代码输出什么?
难度: 实战
string[] parts = "a,,b,".Split(',');
Console.WriteLine(parts.Length);
- A.
2 - B.
3 - C.
4,默认保留空子串,尾部分隔符也产生空项 - D. 运行抛
ArgumentException
查看答案与解析
正确答案C
解析: Split 默认保留空项,"a,,b," 按 , 切出 ["a", "", "b", ""] 共 4 项;需要过滤空项必须显式传 StringSplitOptions.RemoveEmptyEntries。
关键点: 分隔符相邻或结尾都会产生空字符串,别默认它们会被忽略。
0433 以下代码输出什么?
难度: 实战
try
{
"abc".Substring(1, 3);
}
catch (Exception ex)
{
Console.WriteLine(ex.GetType().Name);
}
- A.
FormatException - B.
ArgumentOutOfRangeException - C.
IndexOutOfRangeException - D. 不抛异常,输出
abc
查看答案与解析
正确答案B
解析: "abc".Substring(1, 3) 要求从索引 1 取 3 个字符,超出长度,抛 ArgumentOutOfRangeException(参数校验异常,不是 IndexOutOfRangeException)。
关键点: Substring 的越界属于参数错误;长度不足时 Substring(1) 可以,Substring(1, 3) 不行。
0434 以下代码输出什么?
难度: 实战
string s = "hello";
Console.WriteLine(s[^3..^1]);
- A.
hel - B.
ell - C.
llo - D.
ll
查看答案与解析
正确答案D
解析: ^3..^1 展开为 2..4,取索引 2、3 的字符,即 "ll";Range 切片对字符串同样适用,终点开区间。
关键点: 字符串 Range 切片也会生成新字符串;只有 AsSpan() 切片不分配。
0435 以下代码输出什么?
难度: 进阶
Console.WriteLine(string.CompareOrdinal("A", "a"));
Console.WriteLine(string.Compare("A", "a", StringComparison.OrdinalIgnoreCase));
- A.
-32和0 - B.
1和0 - C.
-1和1 - D.
32和1
查看答案与解析
正确答案A
解析: 序号比较按码点:'A'(65) 小于 'a'(97),差值为 -32;OrdinalIgnoreCase 忽略大小写,比较结果为 0。
关键点: 序号比较看码点差,不是简单的 -1/1;忽略大小写不等于转小写后比较。
0436 关于默认插值字符串处理器 DefaultInterpolatedStringHandler,哪项正确?
难度: 进阶
- A. 插值结果会被缓存到静态池,下次直接复用
- B. 使用它之后插值字符串不再分配任何内存
- C. 编译器选择该结构体逐段调用
AppendLiteral/AppendFormatted,减少中间字符串分配,但最终仍会分配结果字符串 - D. 只有显式调用
string.Format才会使用它
查看答案与解析
正确答案C
解析: 插值字符串默认编译为 DefaultInterpolatedStringHandler 的调用序列:先 AppendLiteral 再 AppendFormatted,把各段直接写入缓冲,避免 string.Format 式的装箱与中间拼接,但 ToString() 仍要产出最终字符串。
关键点: 处理器优化的是“中间过程”,最终结果字符串必然存在。
0437 关于字符串不可变性与线程安全,哪项正确?
难度: 进阶
- A. 字符串不可变,因此任何字符串操作都不会产生新对象
- B. 字符串不可变,多个线程共享同一引用无需加锁也不会互相影响;但
StringBuilder等可变类型不在此列 - C. 不可变性只是习惯约定,通过反射可以安全修改字符串内容
- D. 不可变性只对编译期字面量生效,运行期创建的字符串可变
查看答案与解析
正确答案B
解析: 不可变意味着没有“写者”,共享引用天然线程安全;可变对象(如 StringBuilder、char[])需要同步。反射修改字符串是危险的黑科技,不在契约内。
关键点: “不可变 → 可安全共享”成立,但不能倒推成“操作零分配”。
0438 以下代码输出什么?
难度: 实战
string? a = null;
Console.WriteLine(string.Concat(a, "x").Length);
- A. 运行抛
ArgumentNullException - B. 输出
0 - C. 编译失败
- D. 输出
1,Concat把 null 当空串处理
查看答案与解析
正确答案D
解析: string.Concat 对 null 实参按空字符串处理,null + "x" 结果为 "x",长度为 1;+ 运算符对字符串同样容忍 null。
关键点: 字符串拼接系列 API 都把 null 当作空串,不会抛异常。
0439 关于字符串比较的默认语义,哪项正确?
难度: 进阶
- A.
==与string.Equals(string)是序号(ordinal)比较;string.CompareTo默认使用当前区域性规则 - B.
==与CompareTo语义完全相同 - C.
StringComparison只影响 Linux 上的行为 - D.
==永远做引用比较
查看答案与解析
正确答案A
解析: string 的 == 和实例 Equals(string) 都是序号比较;而 string.CompareTo 走“当前区域性、区分大小写”的排序规则,两个 API 家族语义不同,混用是常见坑。
关键点: 判断相等用 Equals/==,排序比较用 Compare/CompareTo,且显式传 StringComparison 最稳妥。
0440 以下代码输出什么?
难度: 进阶
string? a = null;
string? b = null;
Console.WriteLine(string.Equals(a, b));
Console.WriteLine(a == b);
- A.
True和False - B.
False和False - C.
True和True,静态Equals与==对两个 null 都判等 - D. 运行抛
NullReferenceException
查看答案与解析
正确答案C
解析: string.Equals(a, b) 静态方法与 a == b 都先处理 null:两个 null 相等,返回 True;只有调用实例方法 a.Equals(b) 才会对 null 引用抛异常。
关键点: null 与 null 判等是 True;“null.Equals(…)”才是 NRE。