С# 6 Улучшенное разрешение перегрузки - уточнение?

Среди всех новых функций на С# 6 самая загадочная функция (для меня) - это "улучшенное разрешение перегрузки".

Может быть, потому что я не смог найти соответствующую информацию/примеры/объяснение об этом.

Единственные две оставшиеся функции, которые не обсуждаются, - это поддержка определения настраиваемый метод добавления расширений для помощи с инициализаторами коллекции, и небольшое, но улучшенное разрешение перегрузки

Глядя на roslyn wiki

Существует ряд небольших улучшений разрешения перегрузки, которые скорее всего, приведет к тому, что больше всего будет работать так, как вы ожидаете их к. Все улучшения связаны с "блеском" - способом компилятор решает, какая из двух перегрузок лучше для данного аргумент.

И поэтому я спрашиваю:

Вопрос

Как точно улучшено разрешение перегрузки в С# 6? И как он отличается от С# 5 (Пример? Документация?)

Ответы

Ответ 1

Я верю, что здесь подразумеваются правила "лучшего бытия", которые задокументированы в репозитории github в Roslyn.

Пример кода:

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

Используя компилятор С# 5 (например, в c:\Windows\Microsoft.NET\Framework\v4.0.30319\), это дает две ошибки:

Test.cs(11,9): ошибка CS0121: вызов неоднозначен между следующими способами или свойствами:
      'Test.Foo(System.Action)' и 'Test.Foo(System.Func)'
Test.cs(11,13): ошибка CS0407: 'int Test.Bar()' имеет неправильный тип возврата

Используя компилятор С# 6, он компилируется отлично.

Аналогично, используя точное сопоставление для лямбда-выражений, это порождает неоднозначную ошибку перегрузки с помощью компилятора С# 5, но не для С# 6:

using System;

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

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