前缀 "On" 在 C# 编码中的事件案例中实现了什么?
What does prefix "On" implement in event cases in C# coding?
我认为使用 "On" 作为 C# 方法的前缀存在相当大的混淆。
在 MSDN 文章 "Handling and Raising Event" https://msdn.microsoft.com/en-us/library/edzehd2t(v=vs.110).aspx 中说,
Typically, to raise an event, you add a method that is marked as
protected and virtual (in C#) or Protected and Overridable (in Visual
Basic). Name this method OnEventName; for example, OnDataReceived. The
method should take one parameter that specifies an event data object.
You provide this method to enable derived classes to override the
logic for raising the event. A derived class should always call the
OnEventName method of the base class to ensure that registered
delegates receive the event.
表示 On... 方法是引发一个事件。但是,在许多编码示例中,甚至是 Microsoft 提供的一些示例中,我们都可以看到将事件 On 方法用作事件处理程序,例如此处的 on https://msdn.microsoft.com/en-us/windows/uwp/gaming/tutorial--adding-move-look-controls-to-your-directx-game?f=255&MSPPError=-2147217396
First, let's populate the mouse and touch pointer event handlers. In
the first event handler, OnPointerPressed(), we get the x-y
coordinates of the pointer from the CoreWindow that manages our
display when the user clicks the mouse or touches the screen in the
look controller region.
void MoveLookController::OnPointerPressed(
_In_ CoreWindow^ sender,
_In_ PointerEventArgs^ args)
{
// Get the current pointer position.
uint32 pointerID = args->CurrentPoint->PointerId;
DirectX::XMFLOAT2 position = DirectX::XMFLOAT2( args->CurrentPoint->Position.X, args->CurrentPoint->Position.Y );
auto device = args->CurrentPoint->PointerDevice;
auto deviceType = device->PointerDeviceType;
if ( deviceType == PointerDeviceType::Mouse )
{
// Action, Jump, or Fire
}
// Check if this pointer is in the move control.
// Change the values to percentages of the preferred screen resolution.
// You can set the x value to <preferred resolution> * <percentage of width>
// for example, ( position.x < (screenResolution.x * 0.15) ).
if (( position.x < 300 && position.y > 380 ) && ( deviceType != PointerDeviceType::Mouse ))
{
if ( !m_moveInUse ) // if no pointer is in this control yet
{
// Process a DPad touch down event.
m_moveFirstDown = position; // Save the location of the initial contact.
m_movePointerPosition = position;
m_movePointerID = pointerID; // Store the id of the pointer using this control.
m_moveInUse = TRUE;
}
}
else // This pointer must be in the look control.
{
if ( !m_lookInUse ) // If no pointer is in this control yet...
{
m_lookLastPoint = position; // save the point for later move
m_lookPointerID = args->CurrentPoint->PointerId; // store the id of pointer using this control
m_lookLastDelta.x = m_lookLastDelta.y = 0; // these are for smoothing
m_lookInUse = TRUE;
}
}
}
我的问题是:
- "On"前缀的用法是否真的有这样的歧义,还是我的误解?人们真的在 raising 和 handling 事件方法中都使用 "On" 吗?
- 实现方法raising和handling事件的标准风格是什么?流行的款式有哪些?你推荐的风格是什么?
对于引发事件的class:当"some condition"发生时,调用class中的方法OnSomeCondition()
是有意义的。然后,如果您想将此情况通知外部方,您将在 OnSomeCondition()
方法中引发一个事件 SomeCondition
。
对于处理事件的class:当Visual Studio自动生成一个处理程序方法时,它调用它someClass_SomeCondition
(至少在C#中,这是你标记的你的问题)。第二个文档摘录和示例不是 C#,这可以解释差异(我不知道是否有事件处理程序的 "official" 命名约定)。
然而,当您从引发事件的 class 继承,并且基础 class 遵循 protected virtual
推荐时,'event' 一词变得不明确:您仍然可以处理 SomeCondition
事件,但您也可以选择覆盖 OnSomeCondition()
方法。
所以我不会说On
前缀"is used to raise an event",而是"to handle a condition",你可以选择来引发事件在 OnCondition()
方法中 - 对于消费方,您可以 处理 事件或 覆盖 OnCondition()
行为。这也是第一个文档摘录所说的:
You provide this method to enable derived classes to override the logic for raising the event.
我认为使用 "On" 作为 C# 方法的前缀存在相当大的混淆。
在 MSDN 文章 "Handling and Raising Event" https://msdn.microsoft.com/en-us/library/edzehd2t(v=vs.110).aspx 中说,
Typically, to raise an event, you add a method that is marked as protected and virtual (in C#) or Protected and Overridable (in Visual Basic). Name this method OnEventName; for example, OnDataReceived. The method should take one parameter that specifies an event data object. You provide this method to enable derived classes to override the logic for raising the event. A derived class should always call the OnEventName method of the base class to ensure that registered delegates receive the event.
表示 On... 方法是引发一个事件。但是,在许多编码示例中,甚至是 Microsoft 提供的一些示例中,我们都可以看到将事件 On 方法用作事件处理程序,例如此处的 on https://msdn.microsoft.com/en-us/windows/uwp/gaming/tutorial--adding-move-look-controls-to-your-directx-game?f=255&MSPPError=-2147217396
First, let's populate the mouse and touch pointer event handlers. In the first event handler, OnPointerPressed(), we get the x-y coordinates of the pointer from the CoreWindow that manages our display when the user clicks the mouse or touches the screen in the look controller region.
void MoveLookController::OnPointerPressed(
_In_ CoreWindow^ sender,
_In_ PointerEventArgs^ args)
{
// Get the current pointer position.
uint32 pointerID = args->CurrentPoint->PointerId;
DirectX::XMFLOAT2 position = DirectX::XMFLOAT2( args->CurrentPoint->Position.X, args->CurrentPoint->Position.Y );
auto device = args->CurrentPoint->PointerDevice;
auto deviceType = device->PointerDeviceType;
if ( deviceType == PointerDeviceType::Mouse )
{
// Action, Jump, or Fire
}
// Check if this pointer is in the move control.
// Change the values to percentages of the preferred screen resolution.
// You can set the x value to <preferred resolution> * <percentage of width>
// for example, ( position.x < (screenResolution.x * 0.15) ).
if (( position.x < 300 && position.y > 380 ) && ( deviceType != PointerDeviceType::Mouse ))
{
if ( !m_moveInUse ) // if no pointer is in this control yet
{
// Process a DPad touch down event.
m_moveFirstDown = position; // Save the location of the initial contact.
m_movePointerPosition = position;
m_movePointerID = pointerID; // Store the id of the pointer using this control.
m_moveInUse = TRUE;
}
}
else // This pointer must be in the look control.
{
if ( !m_lookInUse ) // If no pointer is in this control yet...
{
m_lookLastPoint = position; // save the point for later move
m_lookPointerID = args->CurrentPoint->PointerId; // store the id of pointer using this control
m_lookLastDelta.x = m_lookLastDelta.y = 0; // these are for smoothing
m_lookInUse = TRUE;
}
}
}
我的问题是:
- "On"前缀的用法是否真的有这样的歧义,还是我的误解?人们真的在 raising 和 handling 事件方法中都使用 "On" 吗?
- 实现方法raising和handling事件的标准风格是什么?流行的款式有哪些?你推荐的风格是什么?
对于引发事件的class:当"some condition"发生时,调用class中的方法OnSomeCondition()
是有意义的。然后,如果您想将此情况通知外部方,您将在 OnSomeCondition()
方法中引发一个事件 SomeCondition
。
对于处理事件的class:当Visual Studio自动生成一个处理程序方法时,它调用它someClass_SomeCondition
(至少在C#中,这是你标记的你的问题)。第二个文档摘录和示例不是 C#,这可以解释差异(我不知道是否有事件处理程序的 "official" 命名约定)。
然而,当您从引发事件的 class 继承,并且基础 class 遵循 protected virtual
推荐时,'event' 一词变得不明确:您仍然可以处理 SomeCondition
事件,但您也可以选择覆盖 OnSomeCondition()
方法。
所以我不会说On
前缀"is used to raise an event",而是"to handle a condition",你可以选择来引发事件在 OnCondition()
方法中 - 对于消费方,您可以 处理 事件或 覆盖 OnCondition()
行为。这也是第一个文档摘录所说的:
You provide this method to enable derived classes to override the logic for raising the event.