返回题库高级 .NET 刷题C# 选择题 · 第 44 / 50 篇

C# 试题 44:C# 10~12 新特性

0861 以下代码能否编译?

难度: 进阶

namespace Demo
{
    global using System;
}
  • A. 编译通过,全局 using 可以写在任意位置
  • B. 编译通过,但只对 Demo 命名空间生效
  • C. 编译通过,但需要再写一次非全局 using
  • D. 编译失败,global using 必须位于文件顶层、命名空间之外,且先于其他 using
查看答案与解析

正确答案D

解析: global using 只能出现在编译单元顶层(命名空间之外),且必须位于其他非全局 using 之前;写在命名空间内直接编译失败。

关键点: 全局 using 是“文件级”声明,不是“命名空间级”声明。

0862 以下代码能否编译?

难度: 实战

using System.Collections.Generic;
global using System;

class C { }
  • A. 编译通过
  • B. 编译失败,global using 必须位于所有非 global using 之前
  • C. 编译通过,但 global using 被忽略
  • D. 编译通过,两个 using 作用域相同
查看答案与解析

正确答案B

解析: 规则要求 global using 指令必须排在其他 using 指令前面;先写非全局 using 再写 global using 会编译失败。

关键点: global using 有严格的书写位置要求。

0863 关于 global using 的作用域,哪项正确?

难度: 实战

  • A. 对当前项目(编译单元)内所有文件生效,不影响引用该项目的其他项目
  • B. 仅对同一目录下的文件生效
  • C. 对所有引用该项目的项目也生效
  • D. 仅对声明它的文件生效
查看答案与解析

正确答案A

解析: 全局 using 的作用域是当前编译单元,即当前项目内的所有源文件;它不会通过项目引用传播到其他项目,其他项目需要各自声明。

关键点: global using 只在本项目内全局。

0864 以下代码能否编译?

难度: 实战

class A { }

namespace Demo;
  • A. 编译通过,A 属于全局命名空间
  • B. 编译通过,A 属于 Demo
  • C. 编译失败,文件作用域命名空间必须位于文件中所有成员声明之前
  • D. 编译通过,但 namespace 被忽略
查看答案与解析

正确答案C

解析: 文件作用域命名空间必须是文件中(除 using、注释等)的第一个声明;在它之前声明类型属于非法顺序,编译失败。

关键点: 文件作用域命名空间必须在成员声明之前。

0865 以下代码能否编译?

难度: 进阶

namespace A;

namespace B { }
  • A. 编译通过,两个命名空间共存
  • B. 编译失败,文件作用域命名空间与块作用域命名空间不能在同一文件中混用
  • C. 编译通过,B 嵌套在 A 中
  • D. 编译通过,但 B 被忽略
查看答案与解析

正确答案B

解析: 一个源文件只能使用一种命名空间形式:要么文件作用域、要么块作用域;混用两种声明方式编译失败(一个文件也只能有一个文件作用域命名空间)。

关键点: 文件作用域与块作用域命名空间互斥。

0866 以下代码中 A、B 两个类属于哪个命名空间?

难度: 实战

namespace Demo;

class A { }

class B { }
  • A. A 属于全局命名空间,B 属于 Demo
  • B. 编译失败,文件作用域命名空间后不能声明类
  • C. A 属于 Demo,B 属于全局命名空间
  • D. 文件其余部分都属于 Demo,A、B 都是 Demo 的成员
查看答案与解析

正确答案D

解析: 文件作用域命名空间的“作用域”延伸到文件末尾,声明之后所有类型都隐式属于该命名空间,且不需要花括号与缩进。

关键点: 文件作用域命名空间接管整个剩余文件。

0867 以下代码输出什么?

难度: 实战

var p = new Person { Name = "Ada" };
Console.WriteLine(p.Name);

class Person
{
    public required string Name { get; init; }
}
  • A. 输出 Ada,对象初始化器满足 required 要求
  • B. 编译失败,required 不能用于 init
  • C. 运行抛 MissingFieldException
  • D. 输出空串
查看答案与解析

正确答案A

解析: required 成员必须在对象构造时由初始化器或带 [SetsRequiredMembers] 的构造函数赋值;用对象初始化器提供 Name 即满足契约,编译通过并输出 Ada。

关键点: 对象初始化器是满足 required 的合法途径。

0868 以下代码能否编译?

难度: 实战

var p = new Person();

class Person
{
    public required string Name { get; init; }
}
  • A. 编译通过,运行时 Name 为 null
  • B. 编译通过,Name 自动初始化为空串
  • C. 编译失败,缺少 required 成员 Name
  • D. 运行抛 NullReferenceException
查看答案与解析

正确答案C

解析: new Person() 没有为 required 成员 Name 提供值,编译器报 CS9035 错误,阻止编译通过。required 的核心价值就是把“忘了初始化”从运行时问题变成编译期错误。

关键点: required 是编译期强制的初始化契约。

0869 以下代码输出什么?

难度: 进阶

var p = (Person)Activator.CreateInstance(typeof(Person))!;
Console.WriteLine(p.Name ?? "null");

class Person
{
    public required string Name { get; init; }
}
  • A. 编译失败,反射也无法绕过 required
  • B. 编译通过,输出 null;required 只在编译期强制,反射创建不会校验
  • C. 运行抛 MissingMemberException
  • D. 编译通过,输出空串
查看答案与解析

正确答案B

解析: required 是编译期契约,运行时的反射、反序列化等路径不会自动校验;反射创建出的实例 Name 保持 null,程序照常运行。依赖 required 做防御时要意识到它拦不住反射。

关键点: required 只约束编译期,不约束运行时。

0870 以下代码输出什么?

难度: 进阶

var p = new Person();
Console.WriteLine(p.Name ?? "null");

class Person
{
    public required string Name { get; init; }

    [SetsRequiredMembers]
    public Person() { }
}
  • A. 编译失败,[SetsRequiredMembers] 不能用于无参构造器
  • B. 编译失败,必须显式设置 Name
  • C. 编译通过,输出空串
  • D. 编译通过,输出 null;[SetsRequiredMembers] 只是声明“已设置全部 required 成员”,编译期豁免,不保证运行时真正赋值
查看答案与解析

正确答案D

解析: [SetsRequiredMembers] 告诉编译器“该构造函数会设置所有 required 成员”,从而免除调用点的检查,但编译器不验证构造函数体内是否真的赋值,运行时 Name 仍是 null。

关键点: SetsRequiredMembers 是信任声明,不是运行时保证。

0871 以下代码能否编译?

难度: 进阶

var p = new Point(3, 4);
Console.WriteLine(p.Sum());
Console.WriteLine(p.x);

class Point(int x, int y)
{
    public int Sum() => x + y;
}
  • A. 编译失败,类的主构造函数参数不会自动生成同名属性,p.x 无法访问
  • B. 输出 73
  • C. 输出 70
  • D. 输出 7,p.x 有警告但可运行
查看答案与解析

正确答案A

解析: 对普通 class(非 record),主构造函数参数只是参数,被成员体使用时以私有字段形式捕获,但不会生成公开属性;p.x 编译失败。想公开数据要用 record 或显式声明属性。

关键点: 类的主构造函数参数默认不是属性。

0872 以下代码哪项正确?

难度: 进阶

var r = new R(1);
var c = new C(2);
Console.WriteLine(r.X);
Console.WriteLine(c.X);

record R(int X);
class C(int X);
  • A. 输出 12
  • B. 输出 10
  • C. 编译失败:c.X 无法访问。record 的主构造函数参数生成同名属性,class 不会
  • D. 两行都编译失败
查看答案与解析

正确答案C

解析: record 的主构造函数参数会自动生成同名只读属性(R.X 可访问);普通 class 不生成,c.X 编译失败。这是 record 与 class 主构造函数最本质的差异。

关键点: 只有 record 会从主构造函数参数生成属性。

0873 以下代码输出什么?

难度: 实战

var c = new Counter(5);
Console.WriteLine(c.Next());
Console.WriteLine(c.Next());

class Counter(int start)
{
    private int _current = start;
    public int Next() => _current++;
}
  • A. 输出 01
  • B. 输出 56,主构造函数参数在字段初始化器中可见,_current 捕获 start 的值
  • C. 输出 67
  • D. 编译失败,字段初始化器不能引用主构造函数参数
查看答案与解析

正确答案B

解析: 主构造函数参数在成员初始化和成员体中可见;_current = start 用传入的 5 初始化字段,因此连续调用 Next() 输出 5、6。

关键点: 主构造函数参数可以参与字段初始化。

0874 以下代码能否编译?

难度: 进阶

class Base(int v)
{
    protected int GetV() => v;
}

class Derived : Base
{
    public Derived() : base(1) { }
    public int ReadV() => v;
}
  • A. 编译通过,输出 1
  • B. 编译通过,v 默认为 0
  • C. 运行抛 NullReferenceException
  • D. 编译失败,基类主构造函数参数对派生类不可见
查看答案与解析

正确答案D

解析: 基类主构造函数参数被捕获为基类的私有字段,派生类无法直接访问 v;派生类只能通过基类暴露的成员或构造函数传参使用它。

关键点: 主构造函数参数不会“泄漏”给派生类。

0875 以下代码能否编译?

难度: 进阶

class Point(int x)
{
    public Point() { }
}
  • A. 编译失败,带主构造函数的类型中,其他构造函数必须通过 this(…) 链接主构造函数
  • B. 编译通过,两个构造函数并存
  • C. 编译通过,无参构造器自动调用主构造函数
  • D. 运行抛 MissingMethodException
查看答案与解析

正确答案A

解析: 类型带主构造函数后,所有其他构造函数必须显式用 : this(...) 链接主构造函数(否则参数无法获得来源),编译器报错。

关键点: 附加构造函数必须 this(…) 链到主构造函数。

0876 以下代码能否编译?

难度: 进阶

var list = [1, 2, 3];
  • A. 编译通过,推断为 int[]
  • B. 编译通过,推断为 List<int>
  • C. 编译失败,集合表达式需要目标类型,不能用 var 推断
  • D. 编译通过,推断为 IEnumerable<int>
查看答案与解析

正确答案C

解析: 集合表达式 [...] 没有固定的固有类型,必须由目标类型决定(数组、List、Span 等);用 var 无法推断目标类型,编译器报 CS9176。

关键点: 集合表达式必须显式给出目标类型。

0877 以下代码输出什么?

难度: 实战

int[] first = [1, 2];
int[] all = [0, .. first, 3];

Console.WriteLine(string.Join(",", all));
  • A. 输出 1,2,3
  • B. 输出 0,1,2,3,.. 展开元素把 first 的元素展开进新集合
  • C. 输出 0,3
  • D. 编译失败,.. 只能用于数组
查看答案与解析

正确答案B

解析: 集合表达式的展开元素 .. first 会把可迭代对象 first 的元素逐个展开,与字面元素 0、3 一起组成 [0,1,2,3]

关键点: .. 是集合表达式的展开语法。

0878 以下代码输出什么?

难度: 实战

Span<int> s = [1, 2, 3];
Console.WriteLine(s.Length);
  • A. 输出 0
  • B. 编译失败,集合表达式不能转换为 Span
  • C. 抛 InvalidOperationException
  • D. 输出 3,集合表达式可以转换为 Span<T> 等目标类型
查看答案与解析

正确答案D

解析: 集合表达式可以转换为 Span<T>/ReadOnlySpan<T> 等目标类型(编译器按目标类型生成栈上或暂存数组);这里 s 含 3 个元素,Length 为 3。

关键点: 集合表达式的目标类型包括 ref struct。

0879 关于 C# 12 集合表达式可转换的目标类型,哪项正确?

难度: 实战

  • A. 可转换为数组、List<T>Span<T>ImmutableArray<T> 等,但必须有明确目标类型,var 无法推断
  • B. 只能转换为数组
  • C. 只能转换为 List<T>
  • D. 只能用于方法返回值的类型推断
查看答案与解析

正确答案A

解析: 集合表达式是“类型无关”的语法,编译器按目标类型生成对应实现:数组、List<T>Span<T>ImmutableArray<T> 等都支持;没有目标类型(如 var)就无法编译。

关键点: 目标类型决定集合表达式的最终形态。

0880 关于 C# 12 类的主构造函数(class Point(int x, int y)),哪项使用建议正确?

难度: 实战

  • A. 主构造函数参数会自动生成公开属性,适合直接暴露数据
  • B. 主构造函数参数等价于 readonly 字段
  • C. 类的主构造函数参数默认不生成属性,适合短生命周期、仅内部使用的场景;需要公开数据时用 record 或显式声明属性
  • D. 主构造函数只能在 record 上使用
查看答案与解析

正确答案C

解析: 普通类的主构造函数参数只是参数,不会生成公开属性,因此适合依赖注入、短生命周期对象等“用完即弃”的场景;需要把参数暴露成公开数据时,应改用 record(自动生成属性)或显式声明属性。

关键点: 主构造函数是参数机制,不是属性机制。

官方资料

当前分类

C# 选择题

查看全部分类 →
  1. 42C# 试题 42:HttpClient 与网络基础20 题
  2. 43C# 试题 43:比较、格式化与解析20 题
  3. 44C# 试题 44:C# 10~12 新特性20 题
  4. 45C# 试题 45:C# 13 新特性20 题
  5. 46C# 试题 46:C# 14 新特性20 题
ESC

输入关键词开始搜索