C# – Emulate IDispatchEx in C#

c++design-patternsvisitor-pattern

C# 3.0 Extension methods add extensions to the base Type making calling that method on all instances of that Type legal.

Now, JavaScript I know implements IDispatchEx through which it's possible to add methods to a specific instance.

So how do I add a set of methods to an 'instance' of a C# class? I know this is a Dynamic vs. Static Languages holy war territory. 🙂 Let me clarify my intention is NOT that.

I just want to be able to add a set of events to an interface depending on the class implementing that interface.

I was able to do that using 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 += ...
    }  
}  

Then I didn't like SupportedEvents I want to be able to say

new Sample().Clicked +=...

Then I thought JavaScript (I know C# is not JS :))… AND IDispatchEx, IL Weaving, Reflection.Emit etc. etc. and thought may be there's a way to do this… [Design time support would be nice but I can live without]

Yes, I probably could do this "instance augmentation" with a Visitor pattern.
[Not sure if I could get the syntatic sugar though]

Comments?

Best Solution

Well, you could create a DynamicMethod instance for your "new" methods, but statically attaching them to an existing instance at runtime wouldn't work due to the fact it plain wouldn't compile.

You might (I haven't tried this) be able to emit the opcodes into an in-memory assembly, but that's about as far away from being "Syntactically sweet" as you can get (would involve a lot of reflection and InvokeMember calls, I would think)

It also might be worth looking into Extension Methods - although I've never tried attaching events or event-like methods via extension methods...and they are 3.5 only, so that may limit you.

The nicest looking, "pure C#" implementation is probably something very similar to what you've already got with the generic/interface setup...

Honestly, if you're looking for something with true "dynamic support" like this, I'd do this kind of stuff in a DLR-capable language (like IronPython) and call into it from your C# stuff.