1
        private static readonly List<List<T>> data = new List<List<T>>();

        private static void ProcessData(IEnumerable<IEnumerable<T>> data) { }

        private static void ProcessData(IEnumerable<IList<T>> data) { }

        private static void ProcessData(IList<IEnumerable<T>> data) { }

        private static void ProcessData(IList<IList<T>> data) { }

        static void Main(string[] args)
        {
            ProcessData(data);
        }
  1. Which overload is called?
  2. Why?
  3. How to call the other ones without explicit cast?
Vlad Nan
  • 61
  • 1
  • 6
  • 3
    Is this a quiz question? Have you tried running this code? Have you tried doing research? – CodeCaster Nov 08 '19 at 10:13
  • 1
    what is data in your Main function? – EgoPingvina Nov 08 '19 at 10:14
  • 2
    @Ego look at the first line of code. – CodeCaster Nov 08 '19 at 10:14
  • if these are overload methods then I expect all are doing the same thing then you should have only one method ´private static void ProcessData(IEnumerable> data) { }´ if you are trying to do this it is wrong way to implement – Mukul Keshari Nov 08 '19 at 10:16
  • Well, this is actual code from a project, I've just added a couple of overloads for research. Visual Studio shows that IEnumerable> overload will be called. And I have no idea why. I thought it might be 1st or 4th overload, but it's not. – Vlad Nan Nov 08 '19 at 10:24
  • That's confirmed by [Fiddle](https://dotnetfiddle.net/upQLGA). – Fildor Nov 08 '19 at 10:27
  • Interestingly 3 and 4 are not allowed to be called with a `List>` (cannot convert). So 3 and 4 are out which leaves 1 and 2. Overloading goes by "best" fit, and since `IList` is a better fit then `IEnumerable` it ends up choosing 2. –  Nov 08 '19 at 10:45
  • If I change data to List 4th overload is used – Vlad Nan Nov 08 '19 at 10:47

1 Answers1

1

First of all see this answer of John Skeet why overloads 3 and 4 are not allowed to be called with a List<List<string>>: https://stackoverflow.com/a/9006016/10608418

Now that 3 and 4 are out the reason 2 is chosen is because the compiler looks for the "best match": some of this is covered by Eric Lippert in this SO answer: https://stackoverflow.com/a/5174773/10608418

But basically the result is that 2 is the best fit (IList<T> is "stronger" then IEnumerable<T>).

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067