Vi, я не понял полностью смысл твоего поста, а ты, видимо, не понял мой.
VB имеет ссылку
ref, объявленную
As ISomething.
VB смотрит TLB и видит, что ISomething унаследован от IDispatch.
VB пытается скомпилировать
ref.NonExistantMethod() и
отказывается это компилировать.
То, что хочет ger_kar — чтобы VB не отказывался это компилировать, видя унаследованность от IDispatch, а скомпилировал бы это в пару GetIDsOfNames+Invoke.
Но идея, что
было бы неплохо, если бы VB поступал так, дискредитируют идею использования интерфейсов. Потому что идея во многом — в типизации, в сохранении определённой степени контроля над кодом и в отлове тех ошибок, которые можно отлавить на стадии компиляции, именно на этой стадии.
Если бы VB поступал так, как хочет ger_kar, то выгода от использования конкретных интерфейсов для объявления объектных ссылок (в противовес использованию типа Object или Variant для объявления любых объектных ссылок) сводилась бы к автодополнению и увеличению производительности там, где можно применить раннее связывание.
Или другими словами: инструмент, который ругнётся на ошибочный вызов несуществующего метода на стадии компиляции, но тем не менее оставляет программисту возможность вызывать возможно несуществующий метод — намного лучше инструмента, который молча проглотит любой вызов (даже выглядщий как ошибочный), производя код, который во время выполнения всё-таки попытается достучаться до
с-виду-несуществующего метода, при этом лишая программиста возможности быть подвергнутым бдительному контролю со стороны компилятора.
Или ещё другими словами: неявное использование позднего связывания там, где предполагается использование раннего связывания, но нужный член отсутствует, намного хуже явного использования того связывания, какого желает программист.
Или ещё короче: явное лучше неявного.
Что касается этого:
Vi писал(а):но реально не могут быть использованы тем же VB, потому что на одном объекте VB не сможет вызвать методы разных dispinterface.
То возникает вопрос: с чего это вдруг? Здесь ты ошибаешься.
Во-первых, VB прекрасно поддерживает disp-интерфейсы.
Вообще, я не знаю, но относительно интерфейсов существует огромное количество
идиотских мифов, касающийся того, что VB не поддерживает то одно, то другое. Хотя в реальности с поддержкой разных видов интерфейсов у VB всё обстоит намного лучше, чем у тех, кто невежественно заявляет об отсутствии такой поддержки.
Один старый миф гласит, что VB может работать только с интерфейсами, унаследованными от IDispatch. А с теми, которые не унаследованы от IDispatch, а унаследованы прямо или косвенно от IUnknown (но без IDispatch в цепочке наследования) работать якобы не может. Это чушь и профанация. Даже GSerg написал в своё время статью «
Работа с объектами, не поддерживающими IDispatch», где извращался с ассемлерными вставками, вместо того, чтобы просто подключить к проекту подходящую TLB с описанием нужного интерфейса, и где как раз заявляется, что по нормальному с такими объектами работать нельзя (что ЛОЖНО).
Теперь я вижу миф, что VB не работает с disp-интерфейсами.
Это всё ерунда.
VB прекрасно работает с интерфейсами, не унаследованными от IDispatch. Вне зависимости от того, унаследован интерфейс от IDispatch или нет, VB нужно просто иметь описание этого интерфейса (в виде TLB). Всё — этого достаточно, чтобы объявлять типизированные ссылки и осуществлять через них вызовы по механизму раннего связывания.
VB прекрасно работает с самим интерфейсом IDispatch — для этого есть встроенный типа
Object. Этого достаточно, чтобы объявлять AsObject-ссылки и осуществлять через них вызовы через позднее связывание.
VB прекрасно работает с интерфейсами, унаследованными от IDispatch, то есть такими, которые дополняют IDispatch новыми методами. Это просто частный случай пункта-1.
VB прекрасно работает с dual-интерфейсами, то есть с такими, когда по сути существует связанная
пара из обычного и disp-интерфейса. В случае dual-интерфейсов VB позволяет использовать эти интерфейсы при объявлении объектных ссылок и для осуществения вызовов. При этом для вызова VB всегда отдаёт предпочтение обычному интерфейсу (vtable-интерфейсу), а тот факт, что есть ещё сопутствующий disp-интерфейс просто игнорируется. На самом деле не абсолютно всегда, а всегда, кроме случая, когда вызов делает в коде с применением т.н.
именованных аргументов.
И наконец VB прекрасно работает с голыми disp-интерфейсами, то есть такими, у которых нет (то есть
нет вообще) соответствующего парного обыкновенного интерфейса (vtable-интерфейса). VB позволяет использовать такие интерфейсы для объявления объектных ссылок и для осуществления вызовов членов. В
Помимо всего этого (я специально оставил на закуску), VB не просто позволяет работать с чужими объектами, поддерживающими все вышеперечисленные случаи интерфейсов, позволяя программисту декларировать типизированные объектные ссылки и вызывать метода через них. Нет, помимо этого VB допускают, что VB-шные объекты (написанные на VB классы) могут имплементировать все эти
случаи подвиды интерфейсов.
Так что VB-шный класс может имплементировать интерфейс, не унаследованный от IDispatch, а унаследованный сразу от IUnknown.
VB-шный класс априори имплементирует IDispatch.
VB-шный класс может имплементировать интерфейс, унаследованный от IDispatch и дополненный новыми методами.
VB-шный класс может имплементировать dual-интерфейс.
VB-шный класс может имплементировать голый disp-интерфейс (голый в смысле не-dual), у которого отсутствует раннесвязываемая версия.
VB-шный класс может имплементировать сразу кучу разных disp-интерфейсов, а не ограничиваться одним.
VB может работать со своими объектами, реализующими сразу кучу disp-интерфейсов.
VB может работать с чужими объектами, реализующими сразу кучу disp-интерфейсов.
После всего этого утверждение
Vi писал(а):но реально не могут быть использованы тем же VB, потому что на одном объекте VB не сможет вызвать методы разных dispinterface.
выглядит странно.