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

C#能否自定义类数组的变量集合?数组是否具特殊性?

数组与其他集合的本质差异:变量集合 vs 值集合

我一直以为C#里的数组和其他集合并没区别,只是个可变但固定大小的集合。但深入研究后发现,数组本质完全不同——它是变量的集合,而非值的集合。看下面的代码示例:

var array = new MyStruct[] { new MyStruct() };
var list = new List<MyStruct> { new MyStruct() };

array[0].Value = 1; // 合法,直接修改数组中元素的成员
list[0].Value = 2; // 非法,编译报错:无法修改返回值,因为它不是变量

var listElement = list[0];
listElement.Value = 3; // 合法,但只是修改了副本,原List中的元素不受影响

struct MyStruct // 可变结构体
{
    public int Value;
}

基于这个现象,我有两个技术问题:

  1. 能不能在C#中编写自定义集合,模拟数组的行为——作为变量的集合而非值的集合?
  2. 如果无法实现,是不是意味着数组在这个特性上有特殊性,和其他所有集合本质不同?

问题1:可以实现,但依赖C#的ref返回特性

从C# 7.0开始,支持ref返回值的索引器,借助这个特性可以自定义出类似数组行为的集合。比如我们可以写一个RefList<T>,让它的索引器返回ref T,这样就能直接修改值类型元素的成员:

public class RefList<T> where T : struct
{
    private T[] _innerArray;
    public int Count { get; private set; }

    public RefList(int capacity = 4)
    {
        _innerArray = new T[capacity];
        Count = 0;
    }

    public void Add(T item)
    {
        if (Count == _innerArray.Length)
            Array.Resize(ref _innerArray, _innerArray.Length * 2);
        _innerArray[Count] = item;
        Count++;
    }

    // 返回ref T的索引器
    public ref T this[int index]
    {
        get
        {
            if (index < 0 || index >= Count)
                throw new IndexOutOfRangeException();
            return ref _innerArray[index];
        }
    }
}

使用这个集合时,就能像数组一样直接修改值类型成员:

var refList = new RefList<MyStruct>();
refList.Add(new MyStruct());
refList[0].Value = 4; // 合法,直接修改集合中元素的成员

不过这种实现有几个限制:

  • 仅适用于值类型(引用类型本身就是引用,修改成员不需要ref返回)
  • 索引器的ref返回不能用于部分场景,比如迭代器中,也不能直接赋值给非ref变量(除非用ref var声明)

问题2:数组确实有CLR层面的特殊性

数组的这种“直接修改值类型成员”的行为,是CLR原生支持的特殊特性——哪怕在C# 7.0还没引入ref返回的时期,数组的索引器就已经允许这种操作。这是因为数组在CLR中是一种特殊类型,它的索引访问直接对应内存地址的引用,而非返回值的副本。

而自定义集合只能通过C#的ref返回语法模拟这种行为,本质是借助语言特性复刻CLR对数组的原生支持。所以从底层实现来看,数组在这个特性上确实和普通集合有本质区别——它是CLR直接优化的特殊类型,普通集合则需要依赖语言特性来达到类似效果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 06:22:45