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

C#中是否存在只读数组接口(如IReadOnlyArray<T>)?能否扩展Array类?

C# 实现只读数组的实用方案

1. 原生自带的只读接口:IReadOnlyList<T>

C# 里没有专门的IReadOnlyArray<T>接口,但所有数组类型天然实现了IReadOnlyList<T>——这个接口只对外开放读取相关的成员:

  • 只读索引器 T this[int index] { get; }
  • Count 属性

你直接把数组以IReadOnlyList<T>类型返回就行,外部调用者只能通过这个接口读取元素,没法直接调用数组的修改方法(比如索引器赋值、Array.Resize):

// 内部维护可修改的数组
private int[] _internalNumbers = { 1, 2, 3, 4 };

// 对外暴露只读访问
public IReadOnlyList<int> GetNumbers()
{
    return _internalNumbers;
}

注意点

这种方式有个局限:如果外部调用者硬要通过强制类型转换把IReadOnlyList<T>转回int[],还是能修改原数组内容。如果你的场景不需要防范这种非常规操作,这个方案足够简单高效;要是必须绝对杜绝修改,那就得用包装器,但这会创建新对象,不符合你“保留原数组”的诉求。

2. 自定义只读接口的可行性

Array类是密封类(sealed),没法通过继承给它加自定义接口实现。你可以自己定义一个只读接口,但只能通过包装类来实现它——本质上还是包装器方案,没法直接让原生数组实现这个接口。

举个自定义接口的例子:

public interface IReadOnlyArray<T>
{
    T this[int index] { get; }
    int Length { get; }
}

对应的包装类:

public class ReadOnlyArrayWrapper<T> : IReadOnlyArray<T>
{
    private readonly T[] _source;

    public ReadOnlyArrayWrapper(T[] source)
    {
        _source = source ?? throw new ArgumentNullException(nameof(source));
    }

    public T this[int index] => _source[index];
    public int Length => _source.Length;
}

这种方式能提供严格的只读性,但还是绕不开创建包装对象,没法直接复用原数组的接口。

总结

如果只是想通过接口规范外部的访问行为,返回IReadOnlyList<T>是最省心的选择——不用额外造对象,完全利用数组原生的接口实现。要是担心外部强制转换修改,只能退而求其次用包装器,但这就牺牲了你“保留原数组”的需求,得根据实际场景权衡。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 08:52:45