C# 试题 14:模式匹配
0261 以下代码输出什么?
难度: 实战
object o = null;
Console.WriteLine(o is string s);
- A. 输出
False,声明模式对null返回 false,不抛异常 - B. 输出
True - C. 抛
NullReferenceException - D. 编译失败
查看答案与解析
正确答案A
解析: is string s 同时做类型测试与安全绑定;null 不匹配任何类型模式,直接 false,也不会触发 NRE。
关键点: is 类型测试对 null 是“安全失败”。
0262 以下代码能否编译?
难度: 实战
object o = "abc";
if (o is string s)
{
Console.WriteLine(s.Length);
}
Console.WriteLine(s.Length);
- A. 编译通过,输出
3和3 - B. 编译通过,输出
3和0 - C. 编译失败,
s只在模式确定匹配的作用域内可用 - D. 运行抛
NullReferenceException
查看答案与解析
正确答案C
解析: 模式变量 s 的可用域是“编译器能证明已匹配”的范围(if 真分支);if 之外不可见,属编译错误。
关键点: 模式变量的作用域由“匹配证明”决定。
0263 以下代码输出什么?
难度: 进阶
record Point(int X, int Y);
Point? p = null;
Console.WriteLine(p is { X: 0 });
- A. 抛
NullReferenceException - B. 输出
False,属性模式对null直接失败,不会解引用 - C. 输出
True - D. 编译失败
查看答案与解析
正确答案B
解析: { X: 0 } 先判空;p 为 null 时模式整体失败,不会访问 X。这是属性模式与手写解引用的关键区别。
关键点: 属性模式自带 null 短路。
0264 以下代码输出什么?
难度: 进阶
record Point(int X, int Y);
var p = new Point(1, 2);
Console.WriteLine(p is { X: 1 or 2, Y: > 0 });
- A. 编译失败,属性模式里不能嵌套
or - B. 输出
False - C. 编译失败,关系模式只能用于数值 switch
- D. 输出
True,属性值可用or、关系模式等任意子模式
查看答案与解析
正确答案D
解析: 属性模式的值部分可以是任意模式:X: 1 or 2 命中 X = 1,Y: > 0 命中 Y = 2,整体为 true。
关键点: 属性模式 = 属性的子模式组合,表达能力等同独立模式。
0265 以下代码输出什么?
难度: 实战
string s = "abc";
Console.WriteLine(s is { Length: 3 });
- A. 输出
True,属性模式可以直接匹配string.Length - B. 输出
False - C. 编译失败,属性模式不能用于 string
- D. 抛
NullReferenceException
查看答案与解析
正确答案A
解析: { Length: 3 } 通过属性访问器读取 Length(3)并做常量比较。属性模式适用于任何可读属性。
关键点: 属性模式不限自定义类型,内置类型的属性同样适用。
0266 以下代码输出什么?
难度: 实战
int[] arr = { 1, 2, 3 };
Console.WriteLine(arr is [1, .., 3]);
Console.WriteLine(arr is [1, 2]);
- A.
True和True - B.
True和False,[1, .., 3]允许中间任意元素,[1, 2]要求恰好两个元素 - C.
False和False - D. 编译失败,数组不能用列表模式
查看答案与解析
正确答案B
解析: 列表模式按元素逐一匹配;.. 表示“零或多个”,[1, 2] 是精确长度匹配(长度为 3 的数组不命中)。
关键点: 列表模式是“长度 + 逐元素”的组合匹配。
0267 以下代码输出什么?
难度: 进阶
int[] a = Array.Empty<int>();
Console.WriteLine(a is [..]);
Console.WriteLine(a is [_, ..]);
- A.
False和False - B.
False和True - C.
True和False,[..]匹配任意长度(含空),[_, ..]要求至少一个元素 - D.
True和True
查看答案与解析
正确答案C
解析: [..] 对空数组也成立;[_, ..] 明确要求第一个位置有元素,空数组不命中。
关键点: .. 是“可零个”,_ 是“必须一个”。
0268 以下代码输出什么?
难度: 实战
string s = "hello";
Console.WriteLine(s is ['h', ..]);
Console.WriteLine(s is [.., 'o']);
- A.
False和False - B.
True和False - C.
False和True - D.
True和True,字符串可参与列表模式,元素按char匹配
查看答案与解析
正确答案D
解析: 字符串被当作 char 序列支持列表模式:['h', ..] 检查首字符,[.., 'o'] 检查尾字符。
关键点: 列表模式的输入不限于数组,字符串同样适用。
0269 以下代码输出什么?
难度: 进阶
double x = double.NaN;
Console.WriteLine(x is < 0);
Console.WriteLine(x is >= 0);
Console.WriteLine(x is not < 0);
- A.
FalseFalseTrue,NaN与任何数值的关系比较都为假,not取反后为真 - B.
TrueFalseFalse - C.
FalseTrueTrue - D. 编译失败,关系模式不支持
NaN
查看答案与解析
正确答案A
解析: IEEE 754 下 NaN 对所有比较都返回 false;关系模式忠实于此,于是 is not < 0 为 true——这常与直觉冲突。
关键点: NaN 是关系模式里的“三不沾”,注意 not 的翻转。
0270 以下代码输出什么?
难度: 进阶
int x = 1;
Console.WriteLine(x is not 0 or 1);
- A. 输出
False,等价于“不是 0 也不是 1” - B. 输出
True,优先级为not>and>or,实际等价于(not 0) or 1,1使整体为真 - C. 编译失败,模式里不能混用
not与or - D. 输出
False,not只作用于0
查看答案与解析
正确答案B
解析: x is not 0 or 1 解析为 x is (not 0) or 1;x = 1 时 (not 0) 已为真。若想表达“既不是 0 也不是 1”,应写 x is not 0 and not 1 或 x is not (0 or 1)。
关键点: 模式逻辑运算符的优先级与直觉相反,加括号最安全。
0271 以下代码能否编译?
难度: 进阶
int x = 1;
string r = x switch
{
int i => "int",
1 => "one",
_ => "other"
};
Console.WriteLine(r);
- A. 编译通过,输出
int - B. 编译通过,输出
one - C. 编译失败,
int i已覆盖所有int,1分支不可达 - D. 编译通过,输出
other
查看答案与解析
正确答案C
解析: switch 表达式按声明顺序测试;int i 匹配任意 int,后续 1 永远不会命中,编译器报不可达错误。宽泛模式要放后面。
关键点: switch 是顺序求值,前宽后窄会直接编译失败。
0272 以下代码输出什么?
难度: 实战
enum Color { Red, Green, Blue }
static string Name(Color c) => c switch
{
Color.Red => "R",
Color.Green => "G",
Color.Blue => "B"
};
Console.WriteLine(Name(Color.Red));
- A. 编译失败,switch 表达式必须有
_兜底 - B. 编译失败,枚举不能用于 switch 表达式
- C. 运行抛
SwitchExpressionException - D. 输出
R,覆盖全部枚举成员即穷尽,无需_兜底
查看答案与解析
正确答案D
解析: 编译器对枚举/布尔做穷尽性分析:所有成员都有分支即可编译,无需 _。新增枚举成员后未补分支才会报错。
关键点: 枚举 switch 的穷尽性是“成员级”的静态保证。
0273 以下代码输出什么?
难度: 进阶
record Point(int X, int Y);
object o = new Point(1, 2);
Console.WriteLine(o is Point(1, 2));
Console.WriteLine(o is Point(1, _));
- A.
True和True,位置模式通过Deconstruct逐位置匹配 - B.
False和False - C.
True和False - D. 编译失败,record 不支持位置模式
查看答案与解析
正确答案A
解析: record 自动生成 Deconstruct,位置模式据此逐参数匹配;_ 表示“任意值”。两个都命中。
关键点: 位置模式 = 解构 + 模式,二者都基于 Deconstruct。
0274 以下代码输出什么?
难度: 进阶
int[]? a = null;
Console.WriteLine(a is [..]);
- A. 抛
NullReferenceException - B. 输出
False,列表模式对null直接失败 - C. 输出
True - D. 编译失败,可空数组不能用列表模式
查看答案与解析
正确答案B
解析: 与属性模式一样,列表模式对 null 输入短路失败,不做长度/元素访问,也不会抛异常。
关键点: 列表模式自带 null 安全,先判空后匹配。
0275 以下代码输出什么?
难度: 进阶
object? o = null;
Console.WriteLine(o is var v);
- A. 输出
False - B. 抛
NullReferenceException - C. 输出
True,var模式无条件匹配,包括null - D. 编译失败,
var模式不能用于可空对象
查看答案与解析
正确答案C
解析: is var v 不做任何测试,直接绑定并恒为 true——与类型/声明模式不同,var 不排斥 null。需要“非空才匹配”应使用 is { } 或 is not null。
关键点: is var 的“恒真”属性是常见的 null 陷阱。
0276 以下代码输出什么?
难度: 实战
int? x = 5;
Console.WriteLine(x is int i);
Console.WriteLine(x is null);
- A.
False和False - B.
True和True - C.
False和True - D.
True和False,int?有值时命中int i,is null为假
查看答案与解析
正确答案D
解析: int? 的模式匹配先解包:有值时 x is int i 为真并绑定 i;x is null 只在无值时成立。两种模式互补。
关键点: 可空值类型在模式中先被“拆箱判空”。
0277 关于 switch 的模式顺序与 when guard,哪项正确?
难度: 进阶
- A. 分支按声明顺序求值,guard 为假时继续测试后续分支;先出现的宽泛模式会遮蔽后续模式并可能触发不可达错误
- B. 运行时按最具体类型自动重排分支
- C. guard 为假会抛异常终止匹配
- D. 分支求值顺序由编译器随机决定
查看答案与解析
正确答案A
解析: switch 表达式/语句是自上而下的;guard 只是“当前分支不满足则继续”。编译器还做可达性分析,被完全遮蔽的分支直接报错。
关键点: 写 switch 时把最具体的模式放最前。
0278 以下代码能否编译?
难度: 进阶
IEnumerable<int> e = new List<int> { 1, 2, 3 };
Console.WriteLine(e is [1, 2, 3]);
- A. 编译通过,输出
True - B. 编译失败,列表模式要求类型具备
Count/Length与索引器,IEnumerable<int>不具备 - C. 编译通过,输出
False - D. 编译通过,会先枚举再比较
查看答案与解析
正确答案B
解析: 列表模式是“结构匹配”,要求类型可计数(Count/Length)且可索引;IEnumerable<int> 两者皆无,编译失败。接口层面的“序列”不满足模式约束。
关键点: 列表模式认“可索引集合”,不认枚举器。
0279 关于 is 类型测试与强制转换 (T)x 的区别,哪项正确?
难度: 进阶
- A.
is失败时抛InvalidCastException - B. 二者语义完全相同
- C.
is是“测试 + 安全绑定”,失败返回 false、对 null 安全;(T)x失败抛异常 - D.
is只能用于引用类型
查看答案与解析
正确答案C
解析: 声明模式 x is T t 把“类型测试”与“转换绑定”合并为单一安全操作;显式转换在不兼容时抛异常。选型时按“要不要处理失败”决定。
关键点: is = 测试(安全),强制转换 = 转换(可能抛)。
0280 关于模式匹配的静态分析,哪项正确?
难度: 进阶
- A. 编译器从不检查 switch 是否穷尽
- B. 不可达分支只是警告,不影响编译
- C. switch 表达式必须始终写
_ - D. 编译器做穷尽性与可达性分析:枚举/布尔等可穷尽类型无需
_,被完全遮蔽的分支是编译错误
查看答案与解析
正确答案D
解析: C# 编译器对 switch 表达式做穷尽性(exhaustiveness)与可达性(reachability)双向检查:前者免除不必要的 _,后者把“永远轮不到”的分支变成错误。
关键点: 模式匹配的“静态保证”是语言特性的一部分,不是运行时兜底。