Emula IDispatchEx in C #
-
08-07-2019 - |
Domanda
I metodi di estensione C # 3.0 aggiungono estensioni al tipo di base rendendo legale la chiamata di quel metodo su tutte le istanze di quel tipo.
Ora, JavaScript che conosco implementa IDispatchEx attraverso il quale è possibile aggiungere metodi a un'istanza specifica.
Quindi, come posso aggiungere un set di metodi a una 'istanza' di una classe C #? So che questo è un territorio di guerra santa tra lingue dinamiche e statiche. :) Vorrei chiarire che la mia intenzione NON è quella.
Voglio solo essere in grado di aggiungere una serie di eventi a un'interfaccia a seconda della classe che implementa tale interfaccia.
Sono stato in grado di farlo usando 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 += ...
}
}
Quindi non mi è piaciuto SupportedEvents
che vorrei poter dire
new Sample().Clicked +=...
Poi ho pensato che JavaScript (so che C #
non è JS
:)) ... E IDispatchEx
, IL Weaving
, Reflection.Emit
ecc. ecc. e pensato che potrebbe esserci un modo per farlo ... [Il supporto in fase di progettazione sarebbe bello ma posso vivere senza]
Sì, probabilmente potrei fare questo "aumento di istanza" con un modello Visitatore. [Non sono sicuro di riuscire a ottenere lo zucchero sintatico]
Commenti?
Soluzione
Bene, potresti creare un'istanza DynamicMethod per il tuo " nuovo " metodi, ma collegarli staticamente a un'istanza esistente in fase di runtime non funzionerebbe a causa del fatto che semplicemente non si sarebbe compilato.
Potresti potresti (non ho provato questo) essere in grado di emettere i codici operativi in ??un assembly in memoria, ma è molto più lontano dall'essere " Sintatticamente dolce " come puoi ottenere (implicherebbe molte riflessioni e chiamate InvokeMember, penso)
Potrebbe anche valere la pena esaminare i metodi di estensione, anche se non ho mai provato ad associare eventi o metodi simili a eventi tramite metodi di estensione ... e sono solo 3.5, quindi ciò potrebbe limitarti.
Il più bello, "puro C #" l'implementazione è probabilmente qualcosa di molto simile a quello che hai già con la configurazione generico / dell'interfaccia ...
Onestamente, se stai cercando qualcosa con vero "supporto dinamico" in questo modo, farei questo tipo di cose in un linguaggio compatibile con DLR (come IronPython) e chiamerei dal tuo materiale C #.