c# - 传递匿名函数而不是连接事件
c# - Passing anonymous functions instead of hooking up events
我最近发现了 Actions 和匿名函数的使用,以及它们在处理任务时如何变得得心应手。我做了几个测试,将匿名函数传递给 class 以类似于事件的方式工作。
我正在做的一个例子是...
var myForm = new MyForm();
myForm.OnCertainEvent(output => {
//interact with UI based on feedback.
}));
然后在表单本身中,我将设置一个 Action 属性,并将 Action 传递到 OnCertainEvent
方法。
我认为这种语法非常简洁,而不是声明事件、委托并将它们与 +=
语法挂钩。
这会是不好的做法吗?显然它不是传统的,但它有什么负面影响吗?本质上我只是提供一个回调。
自 C# 中的 lambda 以来,这是一种非常常用的模式,但它有优点也有不便之处。
不方便只有一个"receiver"可以作为目标,通过一个事件你可以hook任意多个receiver。
优点,很容易编写即发即弃类型的表达式,而不是挂接到事件。
如果您想探索更多关于如何相互通信的构造 类,请查看委托模式,不是 .net 委托,而是公开可能调用的函数的接口,就像在Java.
不,这样做完全没问题。你想看你自己,不过我会将传递的方法限制在几行之内。真的,这取决于你想在方法中做什么。如果您正在做的事情与 main 方法抽象地分开,那么实际上将它作为一个独立的方法可能会更好。如果它只是一个简单的更改或更新或其他比我认为内联代码更优雅的东西。
尽管如此,请小心使用方法范围之外的本地数据。这是合法的,但如果您 运行 遇到问题,那很有可能就是问题所在。
Would this be bad practice to do?
这是一个非常间接的问题。这实际上取决于几个关键因素,例如:
- 您想在什么地方使用
Action
, Action<T>
代表?
- 您是否为实际处理事件的 class 正确取消了事件处理程序的连接?
- 您是否正在指导连接
Action
或 Action<T>
委托回调作为事件处理程序?
您似乎在尝试将回调指定为事件处理程序,但您的实现方式似乎不正确。看起来你正试图通过一种方法注册你的回调,即 OnCertainEvent
,缺陷是消费者可能会多次调用它,基本上你最终会得到与调用的回调 -- 这有意义吗?
事件是多播的,这意味着您可以连接无限数量的处理程序以作为对触发的单个 event
的回调进行侦听。这是我正在谈论的一个例子,我写了一个快速 .NET Fiddle。这种编写方式永远无法取消订阅听众,因为他们是匿名的,这可能会导致问题。
Obviously it isn't traditional, but does it have any negative effects?
只要您了解后果并正确清理代码,就应该没问题。在您想要处理此类事件的情况下,您可以通过使用 class 的构造函数(在您的特定情况下为 MyForm
)来更安全地执行此操作。这是另一个 .NET Fiddle 来证明这一点。
完全有可能而且超级强大,在我看来现在考虑 "traditional"。自从引入泛型和 lambda expressions 以来,创建您自己的 delegate
实现的想法已经消失了。最后一个link是一个无耻的外挂,我希望所有这些都有意义并回答你的问题!
我最近发现了 Actions 和匿名函数的使用,以及它们在处理任务时如何变得得心应手。我做了几个测试,将匿名函数传递给 class 以类似于事件的方式工作。
我正在做的一个例子是...
var myForm = new MyForm();
myForm.OnCertainEvent(output => {
//interact with UI based on feedback.
}));
然后在表单本身中,我将设置一个 Action 属性,并将 Action 传递到 OnCertainEvent
方法。
我认为这种语法非常简洁,而不是声明事件、委托并将它们与 +=
语法挂钩。
这会是不好的做法吗?显然它不是传统的,但它有什么负面影响吗?本质上我只是提供一个回调。
自 C# 中的 lambda 以来,这是一种非常常用的模式,但它有优点也有不便之处。
不方便只有一个"receiver"可以作为目标,通过一个事件你可以hook任意多个receiver。
优点,很容易编写即发即弃类型的表达式,而不是挂接到事件。
如果您想探索更多关于如何相互通信的构造 类,请查看委托模式,不是 .net 委托,而是公开可能调用的函数的接口,就像在Java.
不,这样做完全没问题。你想看你自己,不过我会将传递的方法限制在几行之内。真的,这取决于你想在方法中做什么。如果您正在做的事情与 main 方法抽象地分开,那么实际上将它作为一个独立的方法可能会更好。如果它只是一个简单的更改或更新或其他比我认为内联代码更优雅的东西。
尽管如此,请小心使用方法范围之外的本地数据。这是合法的,但如果您 运行 遇到问题,那很有可能就是问题所在。
Would this be bad practice to do?
这是一个非常间接的问题。这实际上取决于几个关键因素,例如:
- 您想在什么地方使用
Action
,Action<T>
代表? - 您是否为实际处理事件的 class 正确取消了事件处理程序的连接?
- 您是否正在指导连接
Action
或Action<T>
委托回调作为事件处理程序?
您似乎在尝试将回调指定为事件处理程序,但您的实现方式似乎不正确。看起来你正试图通过一种方法注册你的回调,即 OnCertainEvent
,缺陷是消费者可能会多次调用它,基本上你最终会得到与调用的回调 -- 这有意义吗?
事件是多播的,这意味着您可以连接无限数量的处理程序以作为对触发的单个 event
的回调进行侦听。这是我正在谈论的一个例子,我写了一个快速 .NET Fiddle。这种编写方式永远无法取消订阅听众,因为他们是匿名的,这可能会导致问题。
Obviously it isn't traditional, but does it have any negative effects?
只要您了解后果并正确清理代码,就应该没问题。在您想要处理此类事件的情况下,您可以通过使用 class 的构造函数(在您的特定情况下为 MyForm
)来更安全地执行此操作。这是另一个 .NET Fiddle 来证明这一点。
完全有可能而且超级强大,在我看来现在考虑 "traditional"。自从引入泛型和 lambda expressions 以来,创建您自己的 delegate
实现的想法已经消失了。最后一个link是一个无耻的外挂,我希望所有这些都有意义并回答你的问题!