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

为何List<List<int>>无法隐式转换为IList<IList<int>>?

为什么List<List>不能传入接收IList<IList>的函数?

先看你提供的测试代码:

internal class Program
{
    static void Main(string[] args)
    {
        int[][] jaggedArray = { new int[] { 0 } };
        Console.WriteLine(AcceptsIEnumerable(jaggedArray));
        Console.WriteLine(AcceptsIList(jaggedArray));

        List<List<int>> listArray = new() { new List<int> { 0 } };
        Console.WriteLine(AcceptsIEnumerable(listArray));
        // Not valid! Why?
        //Console.WriteLine(AcceptsIList(listArray));
    }

    static bool AcceptsIEnumerable(IEnumerable<IEnumerable<int>> x)
    {
        return true;
    }
    static bool AcceptsIList(IList<IList<int>> x)
    {
        return true;
    }
}

核心原因是接口的可变性规则和类型安全约束,拆成三点讲清楚:

1. 为什么IEnumerable<IEnumerable>能接收List<List>?

IEnumerable<T>是协变接口(声明时用了out T关键字),协变的核心逻辑是:如果A是B的实现类/子类,那么IEnumerable<A>可以隐式转成IEnumerable<B>。

这里List<int>实现了IEnumerable<int>,所以List<int>属于IEnumerable<int>的“兼容类型”。外层的IEnumerable<IEnumerable<int>>只要求集合能产出IEnumerable<int>类型的元素,List<List<int>>刚好满足——它的每个元素都是List<int>,也就是合法的IEnumerable<int>,所以转换能通过。

2. 为什么IList<IList>不能接收List<List>?

IList<T>是不变接口(声明时没有in或out修饰T),因为它同时包含读操作(比如this[int index]获取元素)和写操作(比如Add(T item)添加元素)。

如果允许List<List<int>>转成IList<IList<int>>,会直接破坏类型安全:

  • 在AcceptsIList函数里,你可以调用x.Add(new int[0])——因为int[]也实现了IList<int>,符合接口的参数要求。
  • 但原来的List<List<int>>只能添加List<int>类型的元素,强行加入int[]会导致运行时类型转换异常。

C#为了避免这种潜在的崩溃,直接在编译阶段就禁止了这种转换。

3. 为什么int[][]能传入IList<IList>?

交错数组int[][]本质是int[]的数组,而int[]本身实现了IList<int>。同时C#对数组有特殊的协变支持(仅限引用类型数组),int[][]可以隐式转换成IList<IList<int>>——虽然调用Add方法会抛出NotSupportedException(因为数组长度固定),但编译时是允许的,因为它结构上符合接口的要求。

简单总结:

  • 协变接口(如IEnumerable<T>)允许“子类型集合”转成“父类型集合”,前提是只做读操作。
  • 不变接口(如IList<T>)因为支持写操作,必须严格匹配类型,杜绝类型安全风险。
  • 数组有特殊的协变规则,所以int[][]能绕过编译限制(但运行时写操作会报错)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 21:35:23