C# 订阅/取消订阅(添加/删除)扩展方法内的事件

C# 订阅/取消订阅(添加/删除)扩展方法内的事件,c#,events,c#-4.0,extension-methods,presenter-first,C#,Events,C# 4.0,Extension Methods,Presenter First,我想创建一个fluent扩展方法,用于订阅(不太重要的是取消订阅)事件。这是一个扩展,使用.RespondBy(Method)代替+=neweventhandler(Method) 我想这样做:object.WhenSomethingChanges.RespondBy(doingthing) 而不是:object.WhenSomethingChanges+=neweventhandler(doingthingthing) 我在谷歌上搜索了很多,虽然我没有完全掌握复杂的细节,但我现在明白了,这与你

我想创建一个fluent扩展方法,用于订阅(不太重要的是取消订阅)事件。这是一个扩展,使用
.RespondBy(Method)
代替
+=neweventhandler(Method)

我想这样做:
object.WhenSomethingChanges.RespondBy(doingthing)

而不是:
object.WhenSomethingChanges+=neweventhandler(doingthingthing)

我在谷歌上搜索了很多,虽然我没有完全掌握复杂的细节,但我现在明白了,这与你是访问本地领域还是公共活动有关

话虽如此,我只是对“如何”做到这一点感兴趣,而不关心“为什么”我的第一次尝试没有成功。如果解决方法失败,至少一个明确的“你不能这样做……永远。”也是有用的信息

通信状态演示者(代码)

使用系统;
使用InspectionStation.模型;
使用InspectionStation.Views;
使用MachineControl.OPC;
命名空间InspectionStation.Presenters
{
公共类通信StatusPresenter
{
//田地
专用ICommu模型;
私人ICommu视图;
//建造师
公共通信状态演示者
(ICommunicationsModel p_模型,ICommunicationsView p_视图)
{
m_模型=p_模型;
m_视图=p_视图;
HookEvents();
}
私人办公室
{
m_模型
.当通信脉冲跳动时
.响应者(设置指示器的状态);
}
//事件处理程序
无效设置指示器的状态(标记发送器、事件参数e)
{
bool State=sender.BooleanValue;
m_view.Set_Communications_Status_Indicator=状态;
}
}
}
响应者

使用系统;
命名空间公共扩展
{
公共静态部分类扩展方法
{
公共静电
无效响应(此)
GenericEventHandler p_事件,
GenericEventHandler p_处理器
)其中TEventArgs:EventArgs
{
p_事件+=新的GenericEventHandler(p_处理程序);
}
}
}

使用系统;
名称空间公用
{
[序列化属性]
公共委托无效GenericEventHandler
(TEventArgs e特森德发送器公司)
其中TEventArgs:EventArgs;
}
ICommunicationsModel

使用系统;
使用公共资源;
使用MachineControl.OPC;
命名空间InspectionStation.Models
{
公共接口ICommunicationsModel
{
事件GenericEventHandler
当通信脉冲跳动时;
}
}
ICommunicationsView

namespace-InspectionStation.Views
{
公共接口ICommunicationsView
{
布尔集合\通信\状态\指示器{Set;}
}
}
因为C#编译器严格要求类外使用的事件必须后跟一个
+=
-=
,即处理程序的附加和分离命令,因此无法在类外扩展和使用该

但是,如果您愿意在类本身上构建更具体的方法,如:

object.RespondWhenSomethingChangesBy(DoingThisOtherThing);
然后,您可以在该方法内部利用扩展方法,因为该类定义了事件。我知道这意味着您将为活动构建大量的锅炉板代码,但如果这是您真正想要的,那么上述代码可能会比以下代码更加精简:

object.WhenSomethingChanges.RespondBy(DoingThisOtherThing);
我完全理解你在这里的立场,并希望微软选择允许事件在未来扩展(我可以想出一些有趣的理由,我会使用它),但在此之前,我想我们将不得不解决它。老实说,我相信有一些很好的理由它最初没有实施,微软在思考这些事情方面做得很好。

给出了答案,我决定做以下作为我模式的一部分

公共类通信状态演示器
{
...
私人办公室
{
m_模型。
当\u通信\u脉冲\u心跳+=新事件处理程序(
设置指示器的状态);
}
//事件处理程序
无效设置指示器的状态(标记发送器、事件参数e)
{
...
}
}
}
没什么特别的。。。只是基于新行自动设置格式,但这似乎是目前最好的解决方案(即,我几乎可以大声阅读代码,以快速说明其意图,而无需借助大量的注释说明)


注意:我将long
GenericEventHandler
重命名为简单的
EventHandler
,因为不太需要特殊的名称。

好吧,这似乎足够确定了!谢谢:)嗯。。。这看起来很有希望,尽管可能比获得更多的努力。基本上,想法是缩短标准
事件
关键字修改器的电路,并尽可能自由地手动传递代理/操作。我还没有尝试实现这一点,链接中也没有一个例子,但所有的部分似乎都在那里,使我的原始问题有一个可能的(尽管不推荐)解决方案。我将在某个时候重新讨论这个问题,看看是否可以得到一个优雅的实现,即使只是为了好玩。