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

C# 试题 06:方法与参数

0101 以下代码能否编译?

难度: 实战

static void Add(ref int x) => x += 10;

int y;
Add(ref y);
Console.WriteLine(y);
  • A. 能编译,输出 10
  • B. 能编译,输出 0
  • C. 能编译,运行抛异常
  • D. 编译失败,y 在传引用前必须已赋值(CS0165)
查看答案与解析

正确答案D

解析: ref 要求实参在调用前处于“已明确赋值”状态;int y; 只是声明未赋值,Add(ref y) 编译报 CS0165。

关键点: ref 是“可读可写”引用,调用方必须先赋值。

0102 以下代码输出什么?

难度: 实战

int[] arr = { 1, 2, 3 };
ref int r = ref arr[1];
r = 99;

Console.WriteLine(arr[1]);
  • A. 2
  • B. 99
  • C. 3
  • D. 编译失败,数组元素不能取引用
查看答案与解析

正确答案B

解析: ref int r = ref arr[1]r 成为数组元素的别名,给 r 赋值即修改 arr[1]

关键点: ref 局部变量是存储位置的别名,不是值拷贝。

0103 以下代码输出什么?

难度: 实战

static bool TryGet(out int value)
{
    value = 42;
    return true;
}

TryGet(out int result);
Console.WriteLine(result);
  • A. 编译失败,result 未初始化
  • B. 能编译,输出 0
  • C. 能编译,运行抛异常
  • D. 能编译,输出 42
查看答案与解析

正确答案D

解析: out 不要求调用前赋值,方法内为 value 赋值 42,result 拿到该值。

关键点: out 的“必须赋值”义务在方法内部,调用方只需提供变量。

0104 以下代码输出什么?

难度: 实战

static void Get(out string s) => s = "hi";

Get(out var msg);
Console.WriteLine(msg);
  • A. 能编译,输出 hi
  • B. 编译失败,out var 不合法
  • C. 能编译,输出空字符串
  • D. 能编译,输出 null
查看答案与解析

正确答案A

解析: out var msg 是 out 变量声明,编译器在方法调用处内联声明变量并接收赋值。

关键点: out var 把声明与传参合二为一,变量在调用点立即可用。

0105 以下代码能否编译?

难度: 进阶

static void M(in int x)
{
    x++;
}
  • A. 编译失败,in 参数是只读的,不能赋值(CS8331)
  • B. 能编译,x 加 1 但不影响调用方
  • C. 能编译,运行抛异常
  • D. 能编译,x 加 1 且影响调用方
查看答案与解析

正确答案A

解析: in 是只读引用参数,方法内对其赋值(含自增)属于编译错误 CS8331。

关键点: in 提供“引用传递的只读视图”,禁止写入。

0106 以下代码能否编译并运行?

难度: 进阶

static void M(in int x) => Console.WriteLine(x);

M(42);
  • A. 编译失败,字面量不能传给 in 参数
  • B. 能编译,输出 0
  • C. 能编译,运行抛异常
  • D. 能编译,输出 42,编译器为字面量创建临时变量
查看答案与解析

正确答案D

解析: 实参不是变量时,编译器会创建一个临时变量以只读引用方式传入,因此 M(42) 合法且输出 42

关键点: in 并不保证“一定按引用传原存储位置”,无法安全取址时会有临时副本。

0107 以下代码输出什么?

难度: 实战

static void M(int a = 1, int b = 2, int c = 3)
{
    Console.WriteLine($"{a}{b}{c}");
}

M(c: 9);
  • A. 139
  • B. 123
  • C. 129
  • D. 编译失败
查看答案与解析

正确答案C

解析: 命名实参 c: 9 只覆盖第三个参数,ab 用默认值,输出 129

关键点: 命名实参可以跳过中间参数,未提供的参数用默认值。

0108 以下代码能否编译?

难度: 进阶

static void M(int x = DateTime.Now.Year)
{
}
  • A. 编译失败,默认参数值必须是编译时常量(CS1736)
  • B. 能编译,默认值在运行时计算
  • C. 能编译,运行抛异常
  • D. 能编译,默认值为 0
查看答案与解析

正确答案A

解析: 可选参数的默认值写入元数据,必须是编译期常量;DateTime.Now.Year 是运行时值,编译报 CS1736。

关键点: 可选参数默认值是“常量契约”,不是运行时求值表达式。

0109 以下代码输出什么?

难度: 实战

static int Sum(params int[] xs)
{
    int t = 0;
    foreach (var v in xs) t += v;
    return t;
}

Console.WriteLine(Sum());
Console.WriteLine(Sum(1, 2, 3));
  • A. 编译失败
  • B. 00
  • C. 06
  • D. 运行抛异常
查看答案与解析

正确答案C

解析: params 允许零个或多个实参:Sum() 得到长度为 0 的空数组,Sum(1, 2, 3) 求和为 6。

关键点: params 调用不传实参是合法的,不会抛异常。

0110 以下代码运行结果是什么?

难度: 进阶

static void M(params object[] args)
{
    Console.WriteLine(args.Length);
}

M(null);
  • A. 输出 0
  • B. 输出 1
  • C. 运行抛 NullReferenceExceptionnull 被当作整个数组而不是单个元素
  • D. 编译失败
查看答案与解析

正确答案C

解析: 当实参能直接匹配数组类型时,编译器选择“数组形式”而不是“展开形式”,args 本身是 null,访问 args.LengthNullReferenceException

关键点: M(null) 传的是整个 params 数组,不是数组里的一个 null 元素。

0111 以下代码输出什么?

难度: 实战

static void M(string a, string b = "B", string c = "C")
{
    Console.WriteLine(a + b + c);
}

M("A", c: "X");
  • A. ABC
  • B. AXC
  • C. 编译失败
  • D. ABX
查看答案与解析

正确答案D

解析: 位置实参 "A"a,命名实参 c: "X"c,中间的 b 用默认值 "B",拼接为 ABX

关键点: C# 7.2 起位置实参后可以跟命名实参,只要顺序不乱。

0112 以下代码输出什么?

难度: 进阶

static ref int Get(int[] arr, int i) => ref arr[i];

int[] nums = { 10, 20, 30 };
Get(nums, 1) = 99;

Console.WriteLine(nums[1]);
  • A. 编译失败,ref 返回不能赋值
  • B. 20
  • C. 30
  • D. 99
查看答案与解析

正确答案D

解析: ref 返回方法返回的是数组元素的引用,可以直接作为赋值目标,nums[1] 被改为 99。

关键点: ref 返回把“方法结果”变成“可写的存储位置”。

0113 以下代码能否编译?

难度: 进阶

static void M(ref int x)
{
    Action a = () => x++;
}
  • A. 编译失败,ref/out/in 参数不能用于 lambda 或本地函数(CS1628)
  • B. 能编译,闭包捕获引用
  • C. 能编译,运行抛异常
  • D. 能编译,但 lambda 不生效
查看答案与解析

正确答案A

解析: 闭包捕获需要稳定的存储位置,ref 参数指向调用方的任意存储,无法安全捕获,编译报 CS1628。

关键点: 想要闭包修改外部值,应使用普通局部变量并在调用时传 ref

0114 以下代码输出什么?

难度: 实战

static void M(params int[] xs) => Console.WriteLine(xs.Length);

int[] arr = { 1, 2, 3, 4 };
M(arr);
  • A. 1
  • B. 编译失败
  • C. 4
  • D. 运行抛异常
查看答案与解析

正确答案C

解析: 实参本身是 int[] 时采用数组形式,直接传递原数组,不再创建新数组,长度 4。

关键点: 传入数组对象时 params 不会复制,热路径可借此避免分配。

0115 以下代码输出什么?

难度: 进阶

static void M(int x, int y = 2) => Console.WriteLine("A");
static void M(int x) => Console.WriteLine("B");

M(1);
  • A. 输出 B,无需补全可选参数的重载更优
  • B. 输出 A
  • C. 编译失败,重载存在歧义
  • D. 运行抛异常
查看答案与解析

正确答案A

解析: 两个重载都能以 1 个实参调用,但 M(int x) 未省略任何可选参数,按“省略可选参数更少者优先”的规则胜出,输出 B

关键点: 带可选参数的重载会让“看似重复”的签名并存,选优规则容易被忽略。

0116 以下代码输出什么?

难度: 进阶

static void M(in int x) => Console.WriteLine("in");
static void M(int x) => Console.WriteLine("value");

int n = 5;
M(n);
  • A. 输出 value,普通按值参数优先于 in 参数
  • B. 输出 in
  • C. 编译失败,重载存在歧义
  • D. 运行抛异常
查看答案与解析

正确答案A

解析: 对普通实参,按值参数在重载解析中优于按 in 引用传递的参数;只有显式写 M(in n) 才会选 in 重载。

关键点: 新增 in 重载不会劫持既有按值调用,但会让调用点行为取决于写法。

0117 以下代码能否编译?若编译,运行结果是什么?

难度: 进阶

static int M(out int x)
{
    throw new Exception("boom");
}

int v;
M(out v);
  • A. 编译失败,out 参数必须在方法返回前赋值
  • B. 能编译,输出 0
  • C. 能编译,运行抛 UnassignedVariableException
  • D. 能编译,方法直接抛异常无需给 out 赋值,运行抛 Exception
查看答案与解析

正确答案D

解析: 确定性赋值规则只要求“正常返回路径上 out 已赋值”;方法直接抛异常时不需要赋值,编译通过,运行时抛 Exception

关键点: out 的赋值义务仅覆盖正常返回路径。

0118 关于 refout 的契约,哪项正确?

难度: 实战

  • A. refout 完全等价
  • B. ref 要求调用前变量已赋值,方法可读写该存储位置;out 不要求调用前赋值,但方法必须赋值后才能正常返回
  • C. out 调用前必须赋值,ref 不必
  • D. 两者都不能用于方法签名重载
查看答案与解析

正确答案B

解析: ref 是读写引用,调用方负有初始化义务;out 把初始化义务转移给方法。二者仅修饰符不同即可构成重载,但调用点语法不同。

关键点: ref 义务在调用方、out 义务在方法内。

0119 关于 in 参数的真实语义,哪项正确?

难度: 进阶

  • A. in 是只读引用传递;当实参不是变量或无法安全取地址时,编译器会复制到临时变量再传入
  • B. in 参数保证总是按引用传递,从不复制
  • C. inref 完全相同
  • D. in 参数可以在方法内重新赋值
查看答案与解析

正确答案A

解析: in 优先以只读引用传递,但实参为字面量、常量、表达式或属性返回值时会产生临时副本,因此“零复制”不是保证,大结构体也未必省下拷贝。

关键点: in 是“可复制也可引用”的只读语义,性能收益要看实参形态。

0120 关于 params 集合(C# 13 起),哪项正确?

难度: 进阶

  • A. params 只能是数组
  • B. params 调用必须至少传一个实参
  • C. params 允许零个或多个实参,C# 13 起支持 Span<T>/ReadOnlySpan<T>List<T> 等集合类型;热路径需关注是否产生临时分配
  • D. params 集合不能在调用时省略参数
查看答案与解析

正确答案C

解析: C# 13 把 params 从“仅数组”扩展到支持 Span、ReadOnlySpan 及实现集合模式的类型;调用方依旧可传零个或多个实参。Span 形式可避免堆分配,而 List<T> 等引用类型集合在展开调用时仍会分配。

关键点: params 集合解决的是“参数个数不定”,分配与否取决于集合类型与调用形式。

官方资料

当前分类

C# 选择题

查看全部分类 →
  1. 04C# 试题 04:运算符与表达式20 题
  2. 05C# 试题 05:流程控制20 题
  3. 06C# 试题 06:方法与参数20 题
  4. 07C# 试题 07:类与构造函数20 题
  5. 08C# 试题 08:访问级别与程序集20 题
ESC

输入关键词开始搜索