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

C# 试题 20:数组、Index 与 Range

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

难度: 实战

object[] items = new string[3];

items[0] = 1;
  • A. 正常运行,1 被装箱写入数组
  • B. 运行抛 ArrayTypeMismatchException
  • C. 编译失败,object[]string[] 不能互相赋值
  • D. 运行抛 InvalidCastException
查看答案与解析

正确答案B

解析: 数组协变允许把 string[] 的引用赋给 object[],但底层数组的元素类型仍是 string;写入不兼容类型时运行期检查失败,抛 ArrayTypeMismatchException

关键点: 协变只放宽“读取”,写入仍受实际元素类型约束。

0382 以下代码能否编译?

难度: 进阶

object[] items = new int[3];
  • A. 编译失败,值类型数组不参与协变
  • B. 编译通过,int[] 可隐式转换为 object[]
  • C. 编译通过,但运行抛 ArrayTypeMismatchException
  • D. 编译通过,且运行正常
查看答案与解析

正确答案A

解析: 数组协变只适用于引用类型;int[]object[] 不存在隐式转换,赋值在编译期就被拒绝。

关键点: “所有数组都能转 object[]”是常见误读,值类型数组除外。

0383 以下代码输出什么?

难度: 实战

int[,] rect = new int[2, 3];
int[][] jag = new int[3][];
jag[0] = new int[1];
jag[1] = new int[2];
jag[2] = new int[3];

Console.WriteLine(rect.Rank + " " + rect.Length + " " + jag.Length);
  • A. 3 6 3
  • B. 2 6 6
  • C. 2 9 3
  • D. 2 6 3
查看答案与解析

正确答案D

解析: rect.Rank 为 2;rect.Length 是元素总数 2 × 3 = 6jag 本身是一维数组,Length 是子数组个数 3。

关键点: 多维数组的 Length 是全部元素数而不是行数,GetLength(i) 才取某一维的长度。

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

难度: 实战

int[][] jag = new int[3][];

Console.WriteLine(jag[0][0]);
  • A. 输出 0
  • B. 编译失败
  • C. 运行抛 NullReferenceException
  • D. 运行抛 IndexOutOfRangeException
查看答案与解析

正确答案C

解析: new int[3][] 只创建外层数组,三个子数组都是 null;访问 jag[0][0] 先对 null 子数组解引用,抛 NullReferenceException

关键点: 交错数组的子数组不会自动初始化。

0385 以下代码输出什么?

难度: 实战

int[] a = { 10, 20, 30, 40 };

Console.WriteLine(a[^1]);
Console.WriteLine(a[^4]);
  • A. 400
  • B. 4010
  • C. 3010
  • D. 运行抛 IndexOutOfRangeException
查看答案与解析

正确答案B

解析: ^n 表示“从末尾数第 n 个”,等价于 Length - n^1a[3] 即 40,^4a[0] 即 10。

关键点: ^n 的语义是 Length - n,不要记成“倒数第 n+1 个”。

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

难度: 进阶

int[] a = { 1, 2, 3 };

Console.WriteLine(a[^0]);
  • A. 输出 3
  • B. 输出 0
  • C. 编译失败
  • D. 运行抛 IndexOutOfRangeException
查看答案与解析

正确答案D

解析: ^0 计算为 Length - 0 = 3,超出最后一个索引,等价于访问 a[3],抛 IndexOutOfRangeException

关键点: ^0 指向“长度位置”而不是“最后一个元素”,是最常见的 Index 陷阱。

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

难度: 实战

int[] a = { 1, 2 };

Console.WriteLine(a[^3]);
  • A. 运行抛 IndexOutOfRangeException
  • B. 输出 1
  • C. 输出 0
  • D. 运行抛 ArgumentOutOfRangeException
查看答案与解析

正确答案A

解析: ^3 计算为 2 - 3 = -1,负索引非法,抛 IndexOutOfRangeException,而不是 ArgumentOutOfRangeException

关键点: ^n 中 n 大于数组长度时越界,异常类型是 IndexOutOfRangeException

0388 以下代码输出什么?

难度: 实战

int[] a = { 1, 2, 3, 4, 5 };
int[] b = a[1..4];
b[0] = 99;

Console.WriteLine(string.Join(",", a));
  • A. 99,2,3,4,5
  • B. 1,99,3,4,5
  • C. 1,2,3,4,5
  • D. 1,2,3,99,5
查看答案与解析

正确答案C

解析: 对数组做 Range 切片会复制出全新数组,b 与原数组不共享存储;修改 b[0] 不影响 a

关键点: 数组的 [1..4] 是拷贝语义;只有 Span/ReadOnlySpan 的切片才是共享视图。

0389 以下代码输出什么?

难度: 实战

int[] a = { 0, 1, 2, 3, 4 };

Console.WriteLine(string.Join(",", a[^3..^1]));
  • A. 1,2,3
  • B. 3,4
  • C. 2,3,4
  • D. 2,3
查看答案与解析

正确答案D

解析: ^3..^1 展开为 (5-3)..(5-1)2..4,包含索引 2、3,对应元素 2,3;Range 终点是开区间。

关键点: Range 的终点开区间,^n 在起点和终点都按 Length - n 计算。

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

难度: 进阶

int[] a = { 1, 2, 3, 4, 5 };

Console.WriteLine(a[3..1].Length);
  • A. 运行抛 ArgumentOutOfRangeException
  • B. 输出 0(空切片)
  • C. 输出 2
  • D. 输出 3
查看答案与解析

正确答案A

解析: Range 要求起点不超过终点;3..1 起点大于终点,数组切片直接抛 ArgumentOutOfRangeException,不会返回空数组或倒序结果。

关键点: a[3..3] 才是空切片,起点大于终点是异常。

0391 以下代码输出什么?

难度: 进阶

int[] a = { 1, 2, 3, 4, 5 };

Console.WriteLine(a[..^0].Length);
Console.WriteLine(a[^0..].Length);
  • A. 05
  • B. 50
  • C. 55
  • D. 第一行抛 IndexOutOfRangeException
查看答案与解析

正确答案B

解析: ..^0 的终点是 Length - 0 = 5,取到完整数组;^0.. 的起点是 5,得到空切片。作为 Range 的终点,^0 合法;只有把它当单个索引 a[^0] 才会越界。

关键点: 同样的 ^0,放在 Range 终点与放在方括号索引里语义不同。

0392 关于 System.Index^ 语法,哪项正确?

难度: 进阶

  • A. ^1 对任何数组都等价于 Length - 1,空数组也安全
  • B. Index 是 ref struct,不能装箱也不能作为字段
  • C. Index 是普通 readonly struct:^nIsFromEnd 为 true,且支持从 int 隐式转换
  • D. ^00 语义完全相同
查看答案与解析

正确答案C

解析: Indexreadonly struct^n 等价于 new Index(n, fromEnd: true)int 可隐式转换为 Index。空数组上 ^1 会越界;^00 在方括号索引中一个越界、一个取首元素,语义不同。

关键点: Index 只是“偏移量 + 方向”的描述,安全与否取决于容器长度。

0393 以下代码输出什么?

难度: 实战

var pool = ArrayPool<int>.Shared;
int[] buf = pool.Rent(10);

Console.WriteLine(buf.Length >= 10);

pool.Return(buf);
  • A. False
  • B. 运行抛 ArgumentException
  • C. 编译失败,使用 ArrayPool 需要 unsafe
  • D. TrueRent 返回的数组长度可能大于请求值
查看答案与解析

正确答案D

解析: 默认池按 2 的幂分桶,Rent(10) 落在容量 16 的桶里,返回长度 16 的数组;契约只保证“不小于请求值”,调用方应只使用前 10 个元素。

关键点: 不要把租借数组的 Length 当成请求值。

0394 以下代码输出什么?

难度: 实战

var pool = ArrayPool<int>.Shared;
int[] buf = pool.Rent(0);

Console.WriteLine(buf.Length);

pool.Return(buf);
  • A. 输出 0
  • B. 输出 16
  • C. 输出 128
  • D. 运行抛 ArgumentOutOfRangeException
查看答案与解析

正确答案A

解析: Rent(0) 被当作合法请求特殊处理,直接返回空数组(长度 0),不会落入最小桶 16。

关键点: 最小桶大小只约束正请求,Rent(0) 不占任何桶。

0395 关于 ArrayPool 的“归还后不得继续使用”契约,哪项正确?

难度: 进阶

  • A. Return 后数组内容会被自动清零,可以继续安全读取
  • B. 归还后不得再访问该数组:池可能已把它复用于其他租借请求,继续读写会破坏数据
  • C. Return 必须在 Rent 后一秒钟内调用,否则抛异常
  • D. Rent 返回的数组长度必然等于请求值
查看答案与解析

正确答案B

解析: Return 只是把数组交回池中,之后数组不再属于调用方;同一数组可能立刻被下一次 Rent 复用,继续使用属于未定义行为。

关键点: ArrayPool 的生命周期契约是“借出期间独占,归还即失效”。

0396 以下代码哪项说法正确?

难度: 实战

var pool = ArrayPool<string>.Shared;
string[] buf = pool.Rent(8);
buf[0] = "secret";

pool.Return(buf);   // 未传 clearArray: true
  • A. Return 时数组内容会被自动清零
  • B. 数组被立即释放,之后无法被其他代码读取
  • C. 数组留在池中且内容保持不变;处理敏感数据时应传 clearArray: true 或归还前自行清理
  • D. 编译失败,ArrayPool<string> 不存在
查看答案与解析

正确答案C

解析: ReturnclearArray 参数默认是 false,不会清零元素;下一次 Rent 可能拿到这份残留数据。敏感数据必须显式清理。

关键点: 默认归还不清零,池是共享的,“别人可能读到你的数据”。

0397 以下模式哪项说法正确?

难度: 进阶

var pool = ArrayPool<int>.Shared;
int[] buf = pool.Rent(64);

try
{
    // 使用 buf 处理数据
}
finally
{
    pool.Return(buf);
}
  • A. finally 中应再次调用 Rent
  • B. try/finally 多余,可以直接 Return
  • C. Return 必须放在 try 块内
  • D. 正确:即使处理过程抛异常,finally 也保证归还,避免长期占用池中数组
查看答案与解析

正确答案D

解析: finally 保证正常路径与异常路径都执行归还;不归还会造成池中的数组被长期占用,甚至迫使池扩容。这是使用 ArrayPool 的标准姿势。

关键点: 借多少还多少,异常路径也要还。

0398 关于 int[,]int[][],哪项正确?

难度: 进阶

  • A. int[,].Length 返回元素总数(行 × 列),int[][] 的每个子数组长度可以不同
  • B. int[,].Length 返回行数
  • C. int[,]int[][] 可以互相隐式转换
  • D. int[,] 支持数组协变
查看答案与解析

正确答案A

解析: 多维数组是“一整块”矩形存储,Length 为全部元素数;交错数组是“数组的数组”,各子数组长度自由。两者类型不同、不能互转;值类型数组不参与协变。

关键点: 矩形与交错是两种布局,Length 的语义也不同。

0399 以下代码输出什么?

难度: 进阶

int[] a = { 1, 2, 3, 4, 5 };
Range r = 1..^1;

Console.WriteLine(string.Join(",", a[r]));
  • A. 2,3
  • B. 2,3,4
  • C. 1,2,3,4
  • D. 1,2,3,4,5
查看答案与解析

正确答案B

解析: Range 是结构体,1..^1 展开为 1..4,取索引 1、2、3,即 2,3,4;终点开区间。

关键点: Range 可以存成变量复用,起止语义与切片表达式一致。

0400 以下代码输出什么?

难度: 实战

var pool = ArrayPool<byte>.Shared;
byte[] buf = pool.Rent(1_500_000);

Console.WriteLine(buf.Length);

pool.Return(buf);
  • A. 1500000
  • B. 1048576
  • C. 2097152
  • D. 运行抛 OutOfMemoryException
查看答案与解析

正确答案C

解析: 默认池按 2 的幂取桶,1_500_000 向上取整到 2^21 = 2_097_152;只要请求小于桶上限,就会得到整桶大小的数组。

关键点: 租借长度是“不小于请求的最小 2 的幂”,大请求同样可能偏大。

官方资料

当前分类

C# 选择题

查看全部分类 →
  1. 18C# 试题 18:事件20 题
  2. 19C# 试题 19:异常处理20 题
  3. 20C# 试题 20:数组、Index 与 Range20 题
  4. 21C# 试题 21:Span 与 Memory20 题
  5. 22C# 试题 22:字符串与文本处理20 题
ESC

输入关键词开始搜索