You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法修改原数组元素?C# Indexer数组包装类测试问题

问题根源

你的Indexer类之所以通不过SetCorrectly和IndexerDoesNotCopyArray测试,核心问题出在构造函数里的这行代码:

this.array = array.Skip(start).Take(length).ToArray();

这行代码会创建原数组的一个副本,之后你通过Indexer做的任何修改,都只会作用在这个副本上,和原始数组完全没关系——这就直接导致测试里验证原数组元素变化的用例全部失败。

修正后的实现方案

我们需要让Indexer直接引用原数组,通过计算偏移量来访问子范围的元素,而不是复制数组。下面是修正后的代码:

using System;

namespace Incapsulation.Weights
{
    public class Indexer
    {
        private readonly double[] _originalArray;
        private readonly int _startOffset;
        public int Length { get; }

        public Indexer(double[] array, int start, int length)
        {
            // 完善参数合法性校验
            if (array == null)
                throw new ArgumentNullException(nameof(array));
            if (start < 0 || start >= array.Length)
                throw new ArgumentOutOfRangeException(nameof(start), "起始索引超出原数组的有效范围");
            if (length < 0 || start + length > array.Length)
                throw new ArgumentOutOfRangeException(nameof(length), "子数组长度超出原数组的可用范围");

            _originalArray = array;
            _startOffset = start;
            Length = length;
        }

        public double this[int index]
        {
            get
            {
                CheckIndexValidity(index);
                return _originalArray[_startOffset + index];
            }
            set
            {
                CheckIndexValidity(index);
                _originalArray[_startOffset + index] = value;
            }
        }

        // 统一校验索引是否越界
        private void CheckIndexValidity(int index)
        {
            if (index < 0 || index >= Length)
                throw new ArgumentOutOfRangeException(nameof(index), "索引超出当前Indexer的有效范围");
        }
    }
}
关键修改点说明
  1. 取消数组复制:直接保存原数组的引用,所有读写操作都会直接作用在原始数组上,这样测试用例里的修改同步需求就能满足
  2. 计算真实索引位置:通过_startOffset + index的方式,把Indexer的相对索引转换成原数组中的绝对索引,实现对子数组范围的映射
  3. 修复参数校验逻辑:原代码里的length < start是错误的判断条件,改成了start + length > array.Length,确保子数组不会超出原数组的边界;同时新增了原数组为null的校验
  4. 提取索引校验逻辑:把索引越界的检查逻辑抽成单独方法,让代码更简洁,也方便统一维护

这样修改后,所有测试用例都能顺利通过:

  • SetCorrectly:修改Indexer的元素会直接同步到原数组对应位置
  • IndexerDoesNotCopyArray:两个Indexer共享同一个原数组,一个修改后另一个能立刻看到变化
  • 长度校验、元素读取的测试也能正常工作

内容的提问来源于stack exchange,提问作者Sergei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:52:25