Ответ 1
Я обнаружил то же самое при обновлении до Visual Studio 2015, так что это не ново с 2017 годом, но оно является новым с 2013 года.
Я сообщил об этом на github:
Проблема в том, что код неоднозначен, а новый компилятор Roslyn более строг на этом, чем предыдущий компилятор.
Проблема была закрыта действием, чтобы изменить документацию вместо возврата к старому поведению, как часть проблемы Добавить информацию о # 4458 в "Разрешение перегрузки .md" # 4922.
В частности, AlekseyTs прокомментировал это:
В интересах будущего здоровья нашего кода разрешения перегрузки мы решили сохранить нарушение (и правильное) поведение. Если мы получим больше, чем этот единственный случай, мы можем захотеть переоценить.
Итак, у вас это есть. Новый компилятор более строг в этом и вам нужно изменить свой код.
Учитывая комментарий выше, AlekseyTs, вы можете подумать о том, чтобы сообщить об этом Microsoft в github в качестве дополнительного такого случая. Если эта проблема становится все более широко распространенной сейчас, когда 2017 год отсутствует, потому что многие люди/компании ждали с обновлением, поскольку в комментарии говорится, что они могут захотеть переоценить.
Кроме того, причина, по которой вы ничего не нашли в (более старой) документации, заключается в том, что это была "скрытая функция" старшего компилятора, как видно из изменения, внесенные в документацию:
Старый компилятор реализовал специальные правила для разрешения перегрузки (не в спецификации языка) при наличии неиспользуемых параметров param-массива, а Roslyn более строгая интерпретация спецификации (теперь исправлена) помешала некоторым программы от компиляции.
(мой акцент)
Когда мы исправили тот же тип проблемы в нашем коде, мы закончили с чем-то вроде этого (пример с использованием вашего кода):
public interface IRepository<T> where T : class
{
T Get(object id, Expression<Func<T, object>>[] tieBreaker, params Expression<Func<T, object>>[] includeExprs);
T Get(object id, string tieBreaker, params string[] includeExprs);
}
обратите внимание на добавление двух параметров tieBreaker
Затем мы просто включили явный параметр в коллекцию с остальными внутри. Если вам нужно вызвать метод без каких-либо дополнительных опций, вы должны добавить третью перегрузку, в которой не должно быть явно указано, какую перегрузку следует вызывать, чтобы ваш конечный интерфейс выглядел следующим образом:
public interface IRepository<T> where T : class
{
T Get(object id);
T Get(object id, Expression<Func<T, object>>[] tieBreaker, params Expression<Func<T, object>>[] includeExprs);
T Get(object id, string tieBreaker, params string[] includeExprs);
}