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

C# 试题 06:方法与参数

101.ref 实参在调用前必须赋值吗?

难度: 实战

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 是“可读可写”引用,调用方必须先赋值。

102.修改 ref 局部变量会影响原数组吗?

难度: 实战

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 局部变量是存储位置的别名,不是值拷贝。

103.out 参数可以为未初始化的变量赋值吗?

难度: 实战

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 的“必须赋值”义务在方法内部,调用方只需提供变量。

104.out var 能否在调用点声明并接收结果?

难度: 实战

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 把声明与传参合二为一,变量在调用点立即可用。

105.in 参数能在方法内自增吗?

难度: 进阶

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

正确答案A

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

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

106.字面量可以传给 in 参数吗?

难度: 进阶

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

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

正确答案D

解析: 调用点省略 in 修饰符时,实参可以是字面量等表达式;编译器会创建一个临时变量,再以只读引用方式传入,因此 M(42) 合法且输出 42。若显式写成 M(in 42),实参必须是可直接引用的变量,代码将无法编译。

关键点: in 参数始终接收只读引用,但该引用可能指向编译器创建的临时副本,而非调用方原有的存储位置。

107.只指定 c 时其余可选参数取什么值?

难度: 实战

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

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

108.可选参数能使用运行时表达式作为默认值吗?

难度: 进阶

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

正确答案A

解析: 可选参数的默认值必须能在编译期确定。语言允许常量表达式,以及特定值类型的 new T()default(T) 表达式;DateTime.Now.Year 需要在运行时求值,因此编译报 CS1736。

关键点: 可选参数默认值不能依赖运行时状态,但允许的形式并不只有常量字面量。

109.params 在零个与多个实参下分别如何传值?

难度: 实战

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 调用不传实参是合法的,不会抛异常。

110.params 调用中的 null 是数组还是单个元素?

难度: 进阶

#nullable enable

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

M(null);
  • A. 输出 0
  • B. 输出 1
  • C. 编译产生 CS8625 警告,运行抛 NullReferenceExceptionnull 被当作整个数组
  • D. 编译失败
查看答案与解析

正确答案C

解析: #nullable enable 下,将 null 传给非可空的数组引用 object?[] 会产生 CS8625 警告,但仍可生成程序。当实参能直接匹配数组类型时,编译器选择“数组形式”而不是“展开形式”,因此 args 本身为 null,访问 args.Length 时抛出 NullReferenceException

关键点: M(null) 传入的是整个 params 数组;若要传入单个 null 元素,应显式使用 M((object?)null)

111.位置实参与命名实参组合时如何绑定参数?

难度: 实战

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 起位置实参后可以跟命名实参,只要顺序不乱。

112.ref 返回值可以直接作为赋值目标吗?

难度: 进阶

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 返回把“方法结果”变成“可写的存储位置”。

113.ref 参数可以被 lambda 捕获吗?

难度: 进阶

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

正确答案A

解析: C# 明确禁止 lambda、匿名方法或查询表达式直接捕获外围方法的 refoutin 参数,本例编译报 CS1628。这项限制用于避免闭包生命周期与按引用参数生命周期发生冲突。

关键点: 若业务允许值拷贝,可先复制到普通局部变量再捕获;这样捕获的是副本,不再保留原参数的引用语义。

114.向 params 参数直接传数组时长度是多少?

难度: 实战

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 不会复制,热路径可借此避免分配。

115.普通重载与省略可选参数的重载谁优先?

难度: 进阶

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

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

正确答案A

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

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

116.按值参数与 in 参数重载时普通调用选择谁?

难度: 进阶

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

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

正确答案A

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

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

117.始终抛异常的方法必须给 out 参数赋值吗?

难度: 进阶

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 的赋值义务仅覆盖正常返回路径。

118.ref 与 out 分别由谁承担初始化义务?

难度: 实战

  • A. refout 完全等价
  • B. ref 要求调用前变量已赋值,方法可读写该存储位置;out 不要求调用前赋值,但方法必须赋值后才能正常返回
  • C. out 调用前必须赋值,ref 不必
  • D. refout 可以仅凭修饰符不同构成重载
查看答案与解析

正确答案B

解析: ref 是读写引用,调用方负有初始化义务;out 把初始化义务转移给方法。方法不能仅凭 refout 的差异构成重载,否则会产生 CS0663;但按值参数可以与 refout 参数构成重载。

关键点: ref 的初始化义务在调用方,out 的赋值义务在方法内;两者也不能单独用于区分重载。

119.in 参数何时会引用临时副本?

难度: 进阶

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

正确答案A

解析: in 参数接收只读引用。调用点省略 in 时,字面量、常量、表达式或普通属性返回值可以先复制到临时变量,再将该临时变量的只读引用传入,因此“零复制”不是保证。显式写出 in 时,实参必须是可直接引用的变量。

关键点: in 始终按只读引用接收参数,但引用目标可能是调用方变量,也可能是编译器创建的临时副本。

120.C# 13 的 params 支持哪些集合类型?

难度: 进阶

  • 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

输入关键词开始搜索