Этот код не будет компилироваться:Неоднозначность расширения вызова метода
using System;
using System.Runtime.CompilerServices;
static class Extensions {
public static void Foo(this A a, Exception e = null, string memberName = "") {
}
public static void Foo<T>(this A a, T t, Exception e = null, string memberName = "")
where T : class, IB {
}
}
interface IB { }
class A { }
class Program {
public static void Main() {
var a = new A();
var e = new Exception();
a.Foo(e); //<- Compile error "ambiguous call"
}
}
Но если удалить последние string
аргументов все в порядке:
public static void Foo(this A a, Exception e = null) {
}
public static void Foo<T>(this A a, T t, Exception e = null)
where T : class, IB {
}
Вопрос - почему эти необязательные string
аргументов нарушить выбор компилятора вызова метода?
Добавлено: осветленный вопрос: Я не понимаю, почему компилятор не может выбрать правильную перегрузку в первом случае, но может сделать это второй?
Отредактировано: [CallerMemberName]
атрибут не является причиной проблемы здесь, так что я удалил его от вопроса.
Просто для пояснения: Удаление атрибута '[CallerMemberName] только * не имеет * эффекта, компилятор выводит ошибку. Удаление всего аргумента '[CallerMemberName] string memberName =" "' * имеет * эффект, код компилируется. Это то, что я наблюдаю. Правильно? –
** C# Спецификация: 7.5.3.2 Лучше член функции: ** * В противном случае, если все параметры MP имеют соответствующий аргумент, тогда как аргументы по умолчанию должны быть заменены как минимум одним необязательным параметром в MQ, тогда MP лучше, чем MQ. * Это правило применяется во втором случае, но не может быть применено в первом случае. – PetSerAl
Если вы удалите атрибут '[CallerMemberName]', но сохраните параметр 'string memberName =" "' в обоих методах, то что происходит? Edit: @OndrejTucny уже сказал, что я вижу после публикации. Все еще хороший вопрос. –