gpt4 book ai didi

c# - C#中的 `event = method`是什么意思

转载 作者:行者123 更新时间:2023-12-04 03:30:06 25 4
gpt4 key购买 nike

我熟悉 C# 中的事件和委托(delegate),并且我已经使用它们很长一段时间了

// Subscribing
SomeEvent += SomeMethod;
// Unsubscribing
SomeEvent -= SomeMethod;
但是,我看到了类似以下的内容
SomeEvent = SomeMethod
它与订阅事件有何不同。在上面的代码中 SomeMethodSomeEvent 时被调用被提出,但它与订阅事件有什么不同,它在幕后做了什么?
编辑
根据@Eldar 和@PMF 的反馈,我发现 SomeEvent = SomeMethod称为单播委托(delegate)使用或单播使用。
为了正确理解它,我快速在 Unity 中设置了一个测试脚本
public class Testing : MonoBehaviour
{
// UnityAction is a simple delegate
// public delegate void UnityAction();
private UnityAction OnTestAction;

private void Start()
{
OnTestAction = OnTestActionHandler;
}

private void OnTestActionHandler()
{
Debug.Log("On Test Action Handler");
}

// Update is basically infinite loop in unity
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
OnTestAction?.Invoke();
}

if (Input.GetKeyDown(KeyCode.A))
{
OnTestAction -= OnTestActionHandler;
}
}
}
在上面的代码中,我发现它与 Subscribing 相同。和 Unsubscribing , 那么我们可以使用 +=而不是 =还是用 +=不好当您只需将事件订阅到单个方法时?

最佳答案

请注意,只有 field-like events可以这样使用:

SomeEvent = SomeMethod;
SomeEvent += SomeMethod;SomeEvent -= SomeMethod;另一方面,可用于所有事件,它们调用 addremove SomeEvent 的访问者分别。
以下是语言规范中类似字段的事件:

Within the program text of the class or struct that contains the declaration of an event, certain events can be used like fields. To be used in this way, an event [...] must not explicitly include event_accessor_declarations. Such an event can be used in any context that permits a field. The field contains a delegate which refers to the list of event handlers that have been added to the event. If no event handlers have been added, the field contains null.


通常,类似事件的字段没有明确的 addremove访问器。
请注意他们如何拥有一个存储事件处理程序列表的委托(delegate)类型字段。 SomeEvent = SomeMethod;基本上将该字段设置为调用列表仅包含 SomeMethod 的委托(delegate)。 .这意味着列表中所有先前的处理程序都将被丢弃。如果您想知道如何将方法名称转换为委托(delegate),请参阅 method group conversions . addremove类字段事件的访问器会自动生成:

When compiling a field-like event, the compiler automatically creates storage to hold the delegate, and creates accessors for the event that add or remove event handlers to the delegate field. The addition and removal operations are thread safe, and may (but are not required to) be done while holding the lock on the containing object for an instance event, or the type object for a static event.


规范没有具体说明如何,所以这取决于实现来决定。在 SharpLab ,我们可以看到一种实现是:
private EventHandler m_SomeEvent;

private event EventHandler SomeEvent
{
[CompilerGenerated]
add
{
EventHandler eventHandler = this.SomeEvent;
while (true)
{
EventHandler eventHandler2 = eventHandler;
EventHandler value2 = (EventHandler)Delegate.Combine(eventHandler2, value);
eventHandler = Interlocked.CompareExchange(ref this.SomeEvent, value2, eventHandler2);
if ((object)eventHandler == eventHandler2)
{
break;
}
}
}
[CompilerGenerated]
remove
{
EventHandler eventHandler = this.SomeEvent;
while (true)
{
EventHandler eventHandler2 = eventHandler;
EventHandler value2 = (EventHandler)Delegate.Remove(eventHandler2, value);
eventHandler = Interlocked.CompareExchange(ref this.SomeEvent, value2, eventHandler2);
if ((object)eventHandler == eventHandler2)
{
break;
}
}
}
}
注意字段 m_SomeEvent ,以及对 Delegate.Remove 的调用和 Delegate.Combine - 这些是将新处理程序添加到处理程序列表中的内容,并从处理程序列表中删除处理程序。

So can we use += instead of = or is it bad to use += when you only have to subscribe event to single method?


+=还不错当您仅订阅一种方法时。事实上,我建议你使用 += .你现在可能会说“我只想订阅一个方法”,但你永远不知道什么时候会改变 :)

关于c# - C#中的 `event = method`是什么意思,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67086586/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com