bradgonesurfing
bradgonesurfing

Reputation: 32192

Not matching the correct overload in C#

I have the following program

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;


class Program
{

    public static string Foo<T>(params T[] items)
    {
        return "A";
    }

    public static string Foo<T>(IEnumerable<T> items)
    {
        return "B";
    }

    static void Main()
    {
        List<int> items = new List<int>(){0,1,23};

        Console.WriteLine(Foo(items));
        Console.WriteLine(Foo("XXX"));

    }
}

which outputs

A
A

rather than

B
A

Given that List is a subclass of IEnumerable why does the generic params form match earlier with the compiler and give an unexpected answer.

Upvotes: 4

Views: 95

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1502226

When the "better function member" part of the spec (section 7.5.3.2) is invoked, the parameter list being considered is in the expanded form (because the first method is only applicable in its expanded form). At that point, you're comparing two invocations like this:

public static string Foo<T>(T[] items)
Foo(new[] { items });

and

public static string Foo<T>(IEnumerable<T> items)
Foo(items);

The conversion from List<int>[] to List<int>[] is a "better conversion" than the conversion from List<T> to IEnumerable<T>, so we don't get as far as the tie-breakers which would otherwise prefer the normal form over the expanded form.

Upvotes: 4

Related Questions