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

C# 试题 07:类与构造函数

0121 以下代码输出什么?

难度: 实战

class A
{
    public int X = Get();
    public A() => Console.WriteLine($"ctor:{X}");

    static int Get()
    {
        Console.Write("init ");
        return 5;
    }
}

new A();
  • A. init ctor:5
  • B. ctor:0
  • C. ctor:5 init
  • D. 编译失败
查看答案与解析

正确答案A

解析: 实例字段初始化器在构造函数体之前按声明顺序执行:先 init ,再进入构造函数体输出 ctor:5

关键点: 字段初始化先于构造函数体,但晚于分配对象。

0122 以下代码输出什么?

难度: 进阶

class Base
{
    public Base() => Console.Write("B");
}

class Derived : Base
{
    private int _x = Init();
    public Derived() => Console.Write("D");

    static int Init()
    {
        Console.Write("I");
        return 1;
    }
}

new Derived();
  • A. BID
  • B. BDI
  • C. IBD
  • D. DIB
查看答案与解析

正确答案C

解析: 构造顺序为:派生类字段初始化器(I)→ 基类构造函数体(B)→ 派生类构造函数体(D)。

关键点: 派生字段初始化先于基类构造函数执行,这是最常见的构造顺序误区。

0123 以下代码输出什么?

难度: 进阶

class C
{
    public static int N = 5;
    static C() => Console.WriteLine("static ctor");
    public C() => Console.WriteLine("instance ctor");
}

Console.WriteLine(C.N);
new C();
new C();
  • A. instance ctor 先输出,static ctor 在第一次创建实例后才执行
  • B. 输出 static ctor5instance ctorinstance ctor
  • C. 输出 5static ctorinstance ctorinstance ctor
  • D. static ctor 每次创建实例都会执行
查看答案与解析

正确答案B

解析: 显式静态构造函数在首次访问该类型(读取静态字段 N)之前运行且只运行一次,随后打印 5,两次 new C() 各打印一次 instance ctor

关键点: 静态构造函数是“首次使用类型前、仅一次”,且先于静态字段的首次读取。

0124 以下代码输出什么?

难度: 进阶

class C
{
    public static int A = GetA();
    static C() => Console.WriteLine($"static ctor A={A}");

    static int GetA()
    {
        Console.Write("GetA ");
        return 1;
    }
}

Console.WriteLine(C.A);
  • A. 输出 GetA 1(无 static ctor 输出)
  • B. 输出 static ctor A=0 GetA 1
  • C. 编译失败
  • D. 输出 GetA static ctor A=1,随后输出 1
查看答案与解析

正确答案D

解析: 静态字段初始化器(GetA )先于静态构造函数体执行,然后运行 static ctor 打印 A=1,最后主程序读取 A 打印 1

关键点: 静态字段初始化按声明顺序先跑完,静态构造函数体最后执行。

0125 以下代码输出什么?

难度: 实战

class Point(int x, int y)
{
    public int Sum => x + y;
}

Console.WriteLine(new Point(3, 4).Sum);
  • A. 0
  • B. 编译失败
  • C. 7
  • D. 12
查看答案与解析

正确答案C

解析: 主构造函数参数 xy 在整个类型体内可见,属性 Sum 计算 3 + 4 = 7

关键点: 主构造函数参数是类型的词法作用域成员,无需字段即可在成员中引用。

0126 以下代码输出什么?

难度: 实战

class Box(int w)
{
    private int _w = w;
    public int W => _w;
}

Console.WriteLine(new Box(9).W);
  • A. 0
  • B. 编译失败,字段初始化器不能访问主构造函数参数
  • C. 9
  • D. 运行抛异常
查看答案与解析

正确答案C

解析: 主构造函数参数可以在字段初始化器中使用:_w 在构造时被赋为 9。

关键点: 普通 class 的主构造函数参数不会自动成为属性,需要显式存储到字段/属性。

0127 以下代码输出什么?

难度: 实战

class C(int x)
{
    public C() : this(1) { }
    public int X => x;
}

Console.WriteLine(new C().X);
  • A. 1
  • B. 0
  • C. 编译失败
  • D. 运行抛异常
查看答案与解析

正确答案A

解析: 带主构造函数的类型仍可声明额外构造函数,额外构造函数必须通过 this(...) 链接到主构造函数;new C()this(1) 传入参数,X 为 1。

关键点: 额外构造函数要用 this(...) 显式把参数交给主构造函数,否则编译失败。

0128 以下代码输出什么?

难度: 实战

class C
{
    public int X { get; set; }
    public C() => Console.Write($"ctor:{X} ");
}

var c = new C { X = 7 };
Console.WriteLine($"after:{c.X}");
  • A. ctor:7 after:7
  • B. ctor:0 after:0
  • C. ctor:0 after:7,对象初始化器在构造函数之后执行
  • D. 编译失败
查看答案与解析

正确答案C

解析: 对象初始化器在构造函数返回后执行:构造时 X 仍为默认值 0,初始化器随后把 X 设为 7。

关键点: 构造函数内读不到对象初始化器设置的值,初始化器执行时机在构造之后。

0129 以下代码输出什么?

难度: 进阶

class Inner
{
    public int V { get; set; }
}

class Outer
{
    public Inner I { get; } = new Inner();
}

var o = new Outer { I = { V = 5 } };
Console.WriteLine(o.I.V);
  • A. 0
  • B. 编译失败,I 是只读属性
  • C. 运行抛 NullReferenceException
  • D. 5,嵌套初始化器对现有对象赋值而不是重新创建
查看答案与解析

正确答案D

解析: I = { V = 5 } 是嵌套对象初始化器,等价于 o.I.V = 5,不会给只读属性 I 重新赋值,因此合法且输出 5。

关键点: 嵌套初始化器改的是成员对象的属性,不是替换外层属性引用。

0130 以下代码输出什么?

难度: 实战

class C
{
    public C() : this(42)
    {
        Console.Write("default ");
    }
    public C(int x) => Console.Write($"int:{x} ");
}

new C();
  • A. int:42 default
  • B. default int:42
  • C. int:42
  • D. 编译失败
查看答案与解析

正确答案A

解析: this(...) 链会先执行被委托的构造函数 C(int),返回后再执行当前构造函数体,输出 int:42 default

关键点: this 构造链的执行顺序是“被委托者先、委托者后”。

0131 以下代码能否编译?

难度: 进阶

class Base
{
    public Base() { }
}

class Derived : Base
{
    public Derived() : this(1), base() { }
    public Derived(int x) { }
}
  • A. 能编译
  • B. 编译失败,构造函数初始化器不能同时使用 thisbase
  • C. 能编译,运行抛异常
  • D. 能编译,但会创建两个对象
查看答案与解析

正确答案B

解析: 构造函数初始化器只能二选一:要么 this(...) 链到同类构造函数,要么 base(...) 链到基类;同时使用是编译错误。

关键点: thisbase 是互斥的构造链入口,基类链由最终那个非 this 构造函数负责。

0132 以下代码输出什么?

难度: 进阶

class C
{
    static C() => throw new InvalidOperationException("boom");
}

try
{
    var c = new C();
}
catch (TypeInitializationException e)
{
    Console.WriteLine(e.InnerException?.GetType().Name);
}
  • A. 输出 TypeInitializationException
  • B. 输出 InvalidOperationException,静态构造函数异常被包装为 TypeInitializationException
  • C. 编译失败
  • D. 输出空
查看答案与解析

正确答案B

解析: 静态构造函数抛出的任何异常都会以 TypeInitializationException 包装后传播,InnerException 是原始异常,因此打印 InvalidOperationException

关键点: 捕获静态初始化失败时要拆 InnerException 才能看到根因。

0133 以下代码输出什么?

难度: 实战

class Base
{
    public Base(int x) => Console.Write(x);
}

class Derived : Base
{
    public Derived() : base(5) { }
}

new Derived();
  • A. 0
  • B. 编译失败
  • C. 5
  • D. 运行抛异常
查看答案与解析

正确答案C

解析: base(5) 显式调用带参数的基类构造函数,输出 5

关键点: 基类没有无参构造函数时,派生类必须用 base(...) 显式链接。

0134 以下代码能否编译?

难度: 实战

class Base
{
    public Base(int x) { }
}

class Derived : Base { }
  • A. 编译失败,没有可用的无参 base() 构造(CS7036)
  • B. 能编译,使用隐式基类构造函数
  • C. 能编译,运行抛异常
  • D. 能编译,x 默认为 0
查看答案与解析

正确答案A

解析: 派生类的隐式构造函数会调用 base(),但基类只有 Base(int),没有可匹配的无参构造函数,编译报 CS7036。

关键点: “基类必须有可调用的构造函数”是继承的基本约束。

0135 以下代码输出什么?

难度: 实战

class Base(int v)
{
    public int V => v;
}

class Derived(int v, int extra) : Base(v)
{
    public int Extra => extra;
}

Console.WriteLine(new Derived(1, 2).V + new Derived(1, 2).Extra);
  • A. 1
  • B. 2
  • C. 编译失败
  • D. 3
查看答案与解析

正确答案D

解析: 派生主构造函数用 Base(v)v 传给基类主构造函数,V 为 1、Extra 为 2,和为 3。

关键点: 主构造函数之间的继承链接就是把参数显式传给 base(...)

0136 以下代码输出什么?

难度: 进阶

class Bag
{
    private Dictionary<string, int> _d = new();
    public int this[string k]
    {
        get => _d.TryGetValue(k, out var v) ? v : 0;
        set => _d[k] = value;
    }
}

var b = new Bag { ["a"] = 1, ["b"] = 2 };
Console.WriteLine(b["a"] + b["b"]);
  • A. 3
  • B. 0
  • C. 编译失败,对象初始化器不支持索引器
  • D. 运行抛异常
查看答案与解析

正确答案A

解析: 对象初始化器支持索引器初始化:["a"] = 1["b"] = 2 分别调用 setter,随后求和得 3。

关键点: 对象初始化器不仅能设置属性,也能设置索引器元素。

0137 以下代码输出什么?

难度: 进阶

class C
{
    public static int X = 1;
    static C() => X = 2;
    public static int Y = 3;
}

Console.WriteLine(C.X + C.Y);
  • A. 4
  • B. 6
  • C. 5
  • D. 3
查看答案与解析

正确答案C

解析: 静态字段初始化器按声明顺序执行:X = 1Y = 3,随后才运行静态构造函数体把 X 改为 2,所以 2 + 3 = 5

关键点: 静态构造函数体在“全部静态字段初始化之后”运行,改写字段会影响最终值。

0138 关于静态构造函数,哪项正确?

难度: 实战

  • A. 静态构造函数在首次访问类型(创建实例或访问静态成员)前运行,且只执行一次;不能显式调用,不能带参数
  • B. 静态构造函数每次创建实例都会执行
  • C. 静态构造函数可以带参数并显式调用
  • D. 静态构造函数中抛出异常不会传播
查看答案与解析

正确答案A

解析: 静态构造函数是 CLR 触发的类型初始化入口:无参数、不可显式调用、进程内每个 AppDomain 至多一次;内部异常会包装为 TypeInitializationException 传播。

关键点: 静态构造的触发时机是“首次使用”,与实例构造次数无关。

0139 关于主构造函数与 record,哪项正确?

难度: 进阶

  • A. class 的主构造函数参数会自动生成公开属性
  • B. 主构造函数只能有一个参数
  • C. 主构造函数与对象初始化器等价
  • D. 主构造函数参数是类的词法作用域一部分;普通 class 不会自动存储为成员,record 的位置参数才会自动生成属性
查看答案与解析

正确答案D

解析: 主构造函数的参数可在字段初始化器、属性与方法中直接引用,但普通 class 需要显式赋值给字段/属性保存;record 的位置参数(record Point(int X, int Y))会自动生成公开属性。

关键点: “有主构造函数参数”不等于“自动成为成员”,class 与 record 行为不同。

0140 关于对象初始化器,哪项正确?

难度: 实战

  • A. 对象初始化器可以给只读属性赋值
  • B. 对象初始化器在构造函数之后执行,可对可写属性/字段或索引器赋值;只读属性只能由构造函数设置
  • C. 对象初始化器在构造函数之前执行
  • D. 对象初始化器只能用于无构造函数类型
查看答案与解析

正确答案B

解析: 初始化器本质是构造函数返回后的一组赋值语句,因此只读属性(无 setter)无法在其中赋值;有构造函数的类型照样可以用初始化器。

关键点: 初始化器的时机(构造之后)决定了它能写什么、不能写什么。

官方资料

当前分类

C# 选择题

查看全部分类 →
  1. 05C# 试题 05:流程控制20 题
  2. 06C# 试题 06:方法与参数20 题
  3. 07C# 试题 07:类与构造函数20 题
  4. 08C# 试题 08:访问级别与程序集20 题
  5. 09C# 试题 09:继承与多态20 题
ESC

输入关键词开始搜索