Эмулировать IDispatchEx на C#
-
08-07-2019 - |
Вопрос
Методы расширения C # 3.0 добавляют расширения к базовому типу, что делает вызов этого метода для всех экземпляры такого рода законность.
Теперь, я знаю, что JavaScript реализует IDispatchEx, с помощью которого можно добавлять методы к определенному экземпляру.
Итак, как мне добавить набор методов к "экземпляру" класса C #?Я знаю, что это Динамичный vs.Территория священной войны статичных языков.:) Позвольте мне уточнить, что мое намерение НЕ в этом.
Я просто хочу иметь возможность добавлять набор событий к интерфейсу в зависимости от класса, реализующего этот интерфейс.
Я смог сделать это, используя дженерики
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
и т.д.и т.д.и подумал, что, может быть, есть способ сделать это...[Поддержка во время разработки была бы хороша, но я могу жить без]
Да, я, вероятно, мог бы сделать это "увеличение экземпляра" с помощью шаблона посетителя.[Хотя не уверен, смогу ли я получить синтаксический сахар]
Комментарии?
Решение
Ну, вы могли бы создать экземпляр DynamicMethod для ваших "новых" методов, но статическое присоединение их к существующему экземпляру во время выполнения не сработало бы из-за того, что он просто не компилировался бы.
Ты мог бы (Я этого не пробовал) иметь возможность передавать коды операций в сборку в памяти, но это примерно настолько далеко от того, чтобы быть "Синтаксически приятным", насколько вы можете получить (я бы подумал, что это потребует много размышлений и вызовов InvokeMember)
Также, возможно, стоит изучить методы расширения - хотя я никогда не пробовал присоединять события или событийноподобные методы с помощью методов расширения ... и они имеют только 3.5, так что это может вас ограничить.
Самая приятная на вид реализация "чистого C #", вероятно, чем-то очень похожа на то, что у вас уже есть с настройкой generic / interface...
Честно говоря, если вы ищете что-то с настоящей "динамической поддержкой" вроде этого, я бы сделал что-то подобное на языке, поддерживающем DLR (например, IronPython), и вызвал бы это из вашего материала C #.