在C#中模拟IDispatchEx

时间:2008-11-21 00:22:04

标签: c# design-patterns visitor-pattern

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:))... AND IDispatchExIL WeavingReflection.Emit等等,等等并且想到可能有办法做到这一点...... [设计时间支持会很好,但我可以没有生活]

是的,我可能会使用访客模式进行“实例扩充”。 [不确定我是否可以获得合成糖]

评论

1 个答案:

答案 0 :(得分:2)

好吧,你可以为你的“新”方法创建一个DynamicMethod实例,但是在运行时将它们静态地附加到现有实例是不行的,因为它不会编译。

可能(我还没有尝试过这个)能够将操作码发送到内存中的程序集中,但这远远不是你能得到的“语法上的甜蜜”(会有很多反思和InvokeMember调用,我想)

它也可能值得研究扩展方法 - 尽管我从未尝试通过扩展方法附加事件或类似事件的方法......它们只是3.5,所以这可能会限制你。

最好看的“纯C#”实现可能与您通用/接口设置已经非常相似......

老实说,如果你正在寻找具有这种真正“动态支持”的东西,我会用支持DLR的语言(比如IronPython)做这种东西,然后从你的C#中调用它。