Подтвердить что ты не робот

Если вызов на основе интерфейса, который использует "динамический", по-прежнему подчиняется правилам разрешения метода С#?

Как я понимаю, каждый язык может иметь собственный обработчик 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), проверяются как часть разрешение перегрузки.

Итак: это ошибка? Или я неправильно его понимаю?

4b9b3361

Ответ 1

Это хорошо известное ограничение связующего, несколько раз спрашивали о SO и тему этой статьи обратной связи. Я процитирую ответ Microsoft:

Это была область, которую мы явно расширили из-за времени при отправке С# 4.0, и мы хотели бы вернуться к этому. Этот конкретный случай методов ISet/IList, которые на самом деле определены на ICollection, является наиболее заметным местом, где не выкапывание через родительские интерфейсы неоправданно ограничивает охват динамической привязки в С#.

Мы надеемся добавить такую ​​поддержку в ближайшее время, хотя эта проблема в настоящее время падает чуть ниже нашей линии сокращения очереди ошибок. Мы отмечаем проблему "Не исправить", чтобы указать, что в настоящий момент мы не отслеживаем эту проблему в следующей версии Visual Studio. Мы будем активировать эту ошибку в следующем году, если мы получим больше, чем ожидалось, через наш список сортировки ошибок, или если мы повторно рассмотрим ошибку для следующей версии.

Что еще не произошло, афайк. В статье не так много голосов.