Пропускающие метод трудности в C# 4.0: динамичный по сравнению с RealProxy

app / locale / <Language> / template / email /

Найти все шаблоны с именами.

6
задан Thom 8 June 2009 в 10:37
поделиться

1 ответ

Начну с длинного ответа. Каждая привязка динамической операции в C # выполняет примерно эти три вещи в следующем порядке:

  1. Попросить объект связать себя, если он реализует IDynamicMetaObjectProvider или является объектом COM, и если это не удается, то ...
  2. операция к операции над обычным-старым-clr-объектом с использованием отражения, и если это не удается, то ...
  3. Возвращает DynamicMetaObject, который представляет собой полную неудачу привязки.

Вы видите вызовы GetType, потому что на шаге 2 связыватель времени выполнения C # размышляет над вами, чтобы попытаться выяснить, есть ли у вас метод "World", который подходит для вызова, и это происходит потому, что реализация приветствия IDynamicMetaObjectProvider, если таковая имеется, не может придумать что-нибудь особенное.

К сожалению для вас, к тому времени, когда создается исключение RuntimeBinderException, мы больше не связываемся. Исключение возникает из фазы выполнения динамической операции в ответ на мета-объект, возвращенный на шаге 3. Единственная возможность для вас поймать его - это фактический сайт вызова.

Так что эта стратегия не работает. чтобы поработать для вас, если вы хотите реализовать method_missing на C #. Однако у вас есть несколько вариантов.

Один простой вариант - реализовать IDynamicMetaObjectProvider в вашем MethodMissingInterceptor и отложить реализацию IDMOP обернутого объекта. В случае сбоя со стороны внутреннего IDMOP вы можете выполнить привязку к чему угодно (возможно, к вызову делегата method_missing, хранящегося в перехватчике). Обратной стороной здесь является то, что это работает только для объектов, которые известны как динамические объекты, например те, которые реализуют IDMOP для начала. Это потому, что вы в основном вставляете себя между шагами 1 и 2.

Другой альтернативой, которую я могу придумать, является реализация IDynamicMetaObjectProvider, и в нем положительно реагировать на каждую привязку, возвращая вызов метода, который (а) производит тот же код, который компилятор C # создал бы для привязки в первую очередь, и (b) перехватывает RuntimeBinderException для вызова метода method_missing. Обратной стороной здесь является то, что это будет довольно сложно - вам нужно будет сгенерировать произвольные типы делегатов и IL, который их использует, против общедоступных типов в сборке связывания среды выполнения C #, которые, откровенно говоря, не предназначены для публичного использования. Но, по крайней мере, у вас не будет метода для всех операций.

Я уверен, что есть другие стратегии, о которых я не думал, например, вы намекаете на использование удаленных прокси. Я не могу представить, как они выглядят, и не могу сказать, будут ли они успешными.

Суть проблемы здесь в том, что в C # 4.0 нет дизайна, который предвосхищает ваше желание сделать это. В частности, вы не можете легко вставить себя между шагами 2 и 3. Это подводит меня к короткому ответу: к сожалению, в C # 4.0 нет method_missing.

17
ответ дан 8 December 2019 в 13:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: