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

使用索引初始化List<T>编译通过却报错,这是C#的Bug吗?

为什么List用索引初始化能编译但运行时抛异常?

这既不是未完成的功能,也不应该被设为编译错误,核心原因在于C#对对象初始化器和集合初始化器的设计逻辑:

  • 两种初始化方式的本质差异
    Dictionary<TKey,TValue>的[0] = "Hello"是利用了C#的索引器赋值初始化:编译器会将其转换为对字典索引器的连续赋值操作,而字典的索引器本身支持新增键值对(不存在的键会自动添加),所以运行正常。
    List的常规初始化{ "Hello", "World" }是集合初始化器:编译器会自动转换为多次调用Add方法,这是集合初始化器的标准行为,针对实现了IEnumerable且有Add方法的类型。

  • 为什么索引赋值初始化对List能编译通过?
    List公开了可写的索引器public T this[int index] { get; set; },而C#的对象初始化器允许对对象的索引器进行赋值操作——编译器只检查语法是否合法、目标类型是否存在对应的索引器,不会验证索引在运行时的有效性。这和你在普通代码里写var list = new List<string>(); list[0] = "a";能编译但运行报错是同一个道理。

  • 为什么不设为编译错误?
    编译器无法在编译阶段预判List的运行时状态:比如以下代码是完全合法且能正常运行的:

    // 初始化时指定容量并填充默认元素,Count为2
    var listB = new List<string>(new string[2])
    {
        [0] = "Hello",
        [1] = "World"
    };
    

    这种情况下索引0和1都是有效的,编译器没有理由禁止这类合法代码。因此,C#设计上选择将索引越界的检查留给运行时,由CLR抛出ArgumentOutOfRangeException,这符合.NET的错误处理原则——运行时异常用于处理只有在执行时才能发现的非法操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 00:40:04