Начну с длинного ответа. Каждая привязка динамической операции в C # делает примерно эти три вещи в следующем порядке:
- Попросить объект связать себя, если он реализует IDynamicMetaObjectProvider или является COM-объектом, и если это не удается, то ...
- Свяжите операцию с операцией над простым-старым-clr-объектом, используя отражение, и если это не удастся, то ...
- Возвращает объект DynamicMetaObject, представляющий полный сбой привязки.
Вы видите вызовы GetType, потому что на шаге 2 связыватель времени выполнения C # размышляет над вами, чтобы попытаться выяснить, есть ли у вас метод "World", который подходит для вызова, и это происходит из-за реализации IDynamicMetaObjectProvider Привет, если есть, не может придумать что-то особенное, чтобы сделать.
К сожалению для вас, к тому времени, когда выдается исключение RuntimeBinderException, мы больше не привязаны. Исключение возникает на этапе выполнения динамической операции в ответ на метаобъект, возвращенный из-за шага 3. Единственная возможность для вас перехватить его - на месте фактического вызова.
Так что эта стратегия не сработает для вас, если вы хотите реализовать method_missing в C #. У вас есть несколько вариантов.
Одним простым вариантом является реализация IDynamicMetaObjectProvider в вашем MethodMissingInterceptor и переход к реализации IDMOP обернутого объекта. В случае сбоя со стороны внутренней IDMOP вы можете связать с чем угодно (возможно, вызовом метода method_missing, хранящегося в перехватчике). Недостатком здесь является то, что это работает только для объектов, которые, как известно, являются динамическими объектами, например те, которые реализуют IDMOP для начала. Это потому, что вы в основном вставляете себя между шагами 1 и 2.
Еще одна альтернатива, о которой я могу подумать, - это реализовать IDynamicMetaObjectProvider и в нем положительно реагировать на каждое связывание, возвращая вызов метода, который (a) генерирует тот же код, который компилятор C # сгенерировал бы для связывания в первую очередь и (b) перехватывает RuntimeBinderException для вызова метода method_missing. Недостатком здесь является то, что это будет довольно сложно - вам нужно будет генерировать произвольные типы делегатов и IL, который их использует, для открытых типов в сборке компоновщика времени выполнения C #, которые, честно говоря, не предназначены для общественного потребления. Но, по крайней мере, вы получите метод отсутствующий для всех операций.
Я уверен, что есть другие стратегии, о которых я не задумывался, например, вы, похоже, намекаете на использование удаленных прокси. Хотя я не могу представить, как они выглядят, и не могу сказать, будут ли они успешными.
Суть проблемы в том, что C # 4.0 не имеет дизайна, который предвосхищает ваше желание сделать это. В частности, вы не можете легко вставить себя между шагами 2 и 3. Это подводит меня к короткому ответу, извините, в C # 4.0 нет method_missing.