1

Why can a List<List<int> not be passed to a function which accepts an IList<IList<int>?

I can see how this type conversion may be hard to infer. However, it seems to work fine when converting to an IEnumerable<IEnumerable<int> or starting with a int[][], as you can see from my test program. I can't understand why some of these type conversions are infered, when others are not.

 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;
        }

    }
andypea
  • 1,343
  • 11
  • 22
  • 1
    TLDR: you can't do this. Suppose you could, then I could take your list of `List`s and insert into it a `object[]` array, which although it is a `IList` it is not a `List`, therefore it would be an unsafe typecast. You need covariance for this to work, and that only works with readonly interfaces. So `IList>` or `IReadOnlyList>` would work. See also https://stackoverflow.com/questions/5832094/covariance-and-ilist – Charlieface Sep 06 '22 at 00:30
  • 1
    Read up on _covariance_ and _contravariance_ – Flydog57 Sep 06 '22 at 01:14
  • @Charlieface Thanks for the tip about readonly interfaces! That's the key difference I couldn't see. – andypea Sep 06 '22 at 01:19

0 Answers0