Если вызов на основе интерфейса, который использует "динамический", по-прежнему подчиняется правилам разрешения метода С#?
Как я понимаю, каждый язык может иметь собственный обработчик dynamic
, поэтому применяются соответствующие правила. Я не уверен, что следующее правильно/неверно; мысли?
Сценарий: два интерфейса (один реализует другой) с помощью некоторых методов:
public interface IA {
void Bar(object o);
}
public interface IB : IA {
void Foo(object o);
}
и базовая реализация:
public class B : IB {
public void Foo(object o) { Console.WriteLine("Foo"); }
public void Bar(object o) { Console.WriteLine("Bar"); }
}
Теперь, с обычным С# (no dynamic
), мы можем получить доступ к методам IA
от цели типа IB
:
IB b = new B();
var o = new { y = "z" };
b.Foo(o.y); // fine
b.Bar(o.y); // fine
Теперь преднамеренно добавьте аргументы dynamic
к аргументам, которые заставляют весь вызов использовать обработку dynamic
(так как в общем случае это может повлиять на разрешение перегрузки, хотя этого здесь не будет):
IB b = new B();
dynamic x = new {y = "z"};
b.Foo(x.y); // fine
b.Bar(x.y); // BOOM!
Что не удается с помощью RuntimeBinderException
:
'IB' не содержит определения для "Bar"
Теперь, что он говорит, совершенно правильно, поскольку IB
не имеет метод Bar
. Однако, как показано в первом примере: при нормальных правилах С# ожидается, что, поскольку тип объявления цели является интерфейсом (IB
), другие интерфейсы, которые, как известно, будут реализованы (т.е. IA
), проверяются как часть разрешение перегрузки.
Итак: это ошибка? Или я неправильно его понимаю?
Ответы
Ответ 1
Это хорошо известное ограничение связующего, несколько раз спрашивали о SO и тему этой статьи обратной связи. Я процитирую ответ Microsoft:
Это была область, которую мы явно расширили из-за времени при отправке С# 4.0, и мы хотели бы вернуться к этому. Этот конкретный случай методов ISet/IList, которые на самом деле определены на ICollection, является наиболее заметным местом, где не выкапывание через родительские интерфейсы неоправданно ограничивает охват динамической привязки в С#.
Мы надеемся добавить такую поддержку в ближайшее время, хотя эта проблема в настоящее время падает чуть ниже нашей линии сокращения очереди ошибок. Мы отмечаем проблему "Не исправить", чтобы указать, что в настоящий момент мы не отслеживаем эту проблему в следующей версии Visual Studio. Мы будем активировать эту ошибку в следующем году, если мы получим больше, чем ожидалось, через наш список сортировки ошибок, или если мы повторно рассмотрим ошибку для следующей версии.
Что еще не произошло, афайк. В статье не так много голосов.