Эмулировать IDispatchEx в C # - PullRequest
0 голосов
/ 21 ноября 2008

C # 3.0 Методы расширения добавляют расширения к базовому типу, делая вызов этого метода во всех экземплярах этого типа допустимым.

Теперь JavaScript, который я знаю, реализует IDispatchEx, с помощью которого можно добавлять методы к конкретному экземпляру.

Итак, как мне добавить набор методов к «экземпляру» класса C #? Я знаю, что это священная военная территория динамических и статических языков. :) Позвольте мне уточнить, что мое намерение это НЕ так.

Я просто хочу иметь возможность добавлять набор событий в интерфейс в зависимости от класса, реализующего этот интерфейс.

Я смог сделать это, используя Generics

inteface ISample<T> { T SupportedEvents; }  

class Sample : ISample<UIWidgetEvent>   {   }  
class Sample2 : ISample<NonVisualUIWidget> { }

class UIWidgetEvent { public EventHandler Clicked; }  
class NonVisualUIWidget {public EventHandler Expired;}

class TestSample
{  
    public void Test()
    {  
        new Sample().SupportedEvents.Clicked += ...
        new Sample2().SupportedEvents.Expired += ...
    }  
}  

Тогда мне не понравилось SupportedEvents Я хочу иметь возможность сказать

new Sample().Clicked +=...

Тогда я подумал, что JavaScript (я знаю, C# не JS:)) ... И IDispatchEx, IL Weaving, Reflection.Emit и т. Д. И т. Д. И т. Д., И подумал, что есть способ сделать это ... [Поддержка времени разработки была бы хороша, но я могу жить без]

Да, я, вероятно, мог бы сделать это "расширение экземпляра" с помощью шаблона Visitor. [Не уверен, смогу ли я получить синтетический сахар, хотя]

Комментарии

1 Ответ

2 голосов
/ 24 декабря 2008

Ну, вы могли бы создать экземпляр DynamicMethod для ваших «новых» методов, но статическое присоединение их к существующему экземпляру во время выполнения не будет работать из-за того, что он просто не скомпилируется.

Вы могли бы (я не пробовал этого) быть в состоянии выдавать коды операций в сборку в памяти, но это примерно так же далеко от "Синтаксически сладкого", как вы можете получить (будет) я бы подумал, что нужно много размышлений и вызовов InvokeMember)

Возможно, стоит также изучить методы расширения - хотя я никогда не пробовал прикреплять события или методы, подобные событиям, с помощью методов расширения ... и их всего 3,5, поэтому это может вас ограничить.

Самая приятная на вид реализация "чистого C #", вероятно, очень похожа на ту, что вы уже получили с помощью настройки generic / interface ...

Честно говоря, если вы ищете что-то с настоящей «динамической поддержкой», как это, я бы делал подобные вещи на языке, поддерживающем DLR (например, IronPython), и вызывал бы это из вашего C # материала.

...