C#6's Improved overload resolution clarification?

Among all the new features in C#6, the most mysterious feature (to me) is the "improved overload resolution".

Maybe it's because I couldn't find related info/examples/explanation about it.

The only two remaining features not discussed are support for defining a custom Add extension method to help with collection initializers, and some minor but improved overload resolution

Looking at the roslyn wiki

There are a number of small improvements to overload resolution, which will likely result in more things just working the way you’d expect them to. The improvements all relate to “betterness” – the way the compiler decides which of two overloads is better for a given argument.

And so I ask:

Question:

How exactly do the Improved overload resolution comes into play in C#6? And how it is different from C#5 (Example? Documentation?)

Jon Skeet
people
quotationmark

I believe what is meant here is the "better betterness" rules which are documented in the Roslyn github repo.

Sample code:

using System;

class Test
{
    static void Foo(Action action) {}
    static void Foo(Func<int> func) {}
    static int Bar() { return 1; }

    static void Main()
    {
        Foo(Bar);        
    }
}

Using the C# 5 compiler (e.g. in c:\Windows\Microsoft.NET\Framework\v4.0.30319\) this gives two errors:

Test.cs(11,9): error CS0121: The call is ambiguous between the following methods or properties:
     'Test.Foo(System.Action)' and 'Test.Foo(System.Func)'
Test.cs(11,13): error CS0407: 'int Test.Bar()' has the wrong return type

Using the C# 6 compiler, it compiles fine.

Likewise using exact matching for lambda expressions, this generates an ambiguous overload error with the C# 5 compiler, but not for C# 6:

using System;

class Test
{
    static void Foo(Func<Func<long>> func) {}
    static void Foo(Func<Func<int>> func) {}

    static void Main()
    {
        Foo(() => () => 7);
    }
}

people

See more on this question at Stackoverflow