C# 订阅方法内的事件,同时从该方法传递额外参数,而不使用lambda表达式

C# 订阅方法内的事件,同时从该方法传递额外参数,而不使用lambda表达式,c#,events,event-handling,C#,Events,Event Handling,所以我有这样一个事件签名: public event EventHandler<OnColorChangedEventArgs> onColorChanged; public class OnColorChangedEventArgs : EventArgs { public Color color; } private void UpdateColor(object sender, RayCaster.OnColorChangedEventArgs eventArgs,

所以我有这样一个事件签名:

public event EventHandler<OnColorChangedEventArgs> onColorChanged;

public class OnColorChangedEventArgs : EventArgs
{
    public Color color;
}
private void UpdateColor(object sender, RayCaster.OnColorChangedEventArgs eventArgs, PositionOnLine positionOnLine)
{
    if (positionOnLine == PositionOnLine.Start)
    {
        _lineRenderer.startColor = eventArgs.color;
    }
    else
    {
        _lineRenderer.endColor = eventArgs.color;
    }
}
public void AddPoint(RayCaster rayCaster, PositionOnLine positionOnLine, Transform transform)
{
    //some irrelevant code

    rayCaster.onColorChanged += (sender, args) => UpdateColor(sender, args, positionOnLine);
}
public void AddPoint(RayCaster rayCaster, PositionOnLine positionOnLine, Transform transform)
{
    //some irrelevant code

    void updateColor(object sender, OnColorChangedEventArgs e)
    {
        UpdateColor(sender, e, positionOnLine);
    }

    rayCaster.onColorChanged += updateColor;
    rayCaster.onColorChanged -= updateColor;
}
如您所见,订阅方法需要的参数比事件调用传递的参数更多。这些额外的参数应该首先从我调用的订阅事件的方法中传递,如下所示:

public event EventHandler<OnColorChangedEventArgs> onColorChanged;

public class OnColorChangedEventArgs : EventArgs
{
    public Color color;
}
private void UpdateColor(object sender, RayCaster.OnColorChangedEventArgs eventArgs, PositionOnLine positionOnLine)
{
    if (positionOnLine == PositionOnLine.Start)
    {
        _lineRenderer.startColor = eventArgs.color;
    }
    else
    {
        _lineRenderer.endColor = eventArgs.color;
    }
}
public void AddPoint(RayCaster rayCaster, PositionOnLine positionOnLine, Transform transform)
{
    //some irrelevant code

    rayCaster.onColorChanged += (sender, args) => UpdateColor(sender, args, positionOnLine);
}
public void AddPoint(RayCaster rayCaster, PositionOnLine positionOnLine, Transform transform)
{
    //some irrelevant code

    void updateColor(object sender, OnColorChangedEventArgs e)
    {
        UpdateColor(sender, e, positionOnLine);
    }

    rayCaster.onColorChanged += updateColor;
    rayCaster.onColorChanged -= updateColor;
}
这是我想要的。然而,据我所知,这是一名匿名代表。
我需要在某个时候取消订阅这个方法。我似乎找不到办法把它变成一个非匿名的代表。我对代理和事件非常陌生,所以请指出任何代码气味。谢谢。

代理签名必须匹配,因此:您不能在这里作弊。如果以后确实需要取消订阅,可以将委托实例存储在某个位置,即

EventHandler=(发送方,参数)=>
UpdateColor(发送方、参数、位置在线);
rayCaster.onColorChanged+=处理程序;
// ... 后来
rayCaster.onColorChanged-=处理程序;

您可以使用如下本地函数:

public event EventHandler<OnColorChangedEventArgs> onColorChanged;

public class OnColorChangedEventArgs : EventArgs
{
    public Color color;
}
private void UpdateColor(object sender, RayCaster.OnColorChangedEventArgs eventArgs, PositionOnLine positionOnLine)
{
    if (positionOnLine == PositionOnLine.Start)
    {
        _lineRenderer.startColor = eventArgs.color;
    }
    else
    {
        _lineRenderer.endColor = eventArgs.color;
    }
}
public void AddPoint(RayCaster rayCaster, PositionOnLine positionOnLine, Transform transform)
{
    //some irrelevant code

    rayCaster.onColorChanged += (sender, args) => UpdateColor(sender, args, positionOnLine);
}
public void AddPoint(RayCaster rayCaster, PositionOnLine positionOnLine, Transform transform)
{
    //some irrelevant code

    void updateColor(object sender, OnColorChangedEventArgs e)
    {
        UpdateColor(sender, e, positionOnLine);
    }

    rayCaster.onColorChanged += updateColor;
    rayCaster.onColorChanged -= updateColor;
}

顺便说一句:事件的名称不应该像…上那样,而应该像颜色改变一样。

好的。在哪些情况下会添加“On”前缀?这不是严格的规则,而是惯例。通常,事件发布者(引发事件的类)会在[YourEventName]上有一个名为OnColorChanged的受保护虚拟方法,例如OnColorChanged,它实际上会引发事件(在您的例子中是ColorChanged)。请参阅MSDN文档中的示例。谢谢,似乎我的约定确实是错误的。但是有一个问题,因为事件是在该事件所属的类中调用的,所以我不需要这个受保护的虚拟方法,因为它只需要从另一个类调用事件,对吗?正如文档中提到的,它允许派生类重写事件调用行为。它不打算被其他类调用,只有子类才能看到这个方法。我不认为我完全理解你的解决方案。我可能不太清楚,但事件声明和UpdateColor方法在不同的类中。我应该在代码中的什么地方声明该处理程序?因为OnColorChangedEventArgs在具有UpdateColor方法声明的类中不是可识别的类型。@Thrindil是的,通常是,否则使用事件就没有意义了!我的示例基于您的
AddPoint
方法;但是,
OnColorChangedEventArgs
是绝对可访问的-您可能只是缺少使用指令的
或限定;尝试按
Ctrl
+
在上面-IDE通常可以为您添加它。您是对的,我在声明中犯了一个错误。我添加了handler作为类变量,并在AddPoint方法中分配它,这允许我在另一个方法中取消订阅它。工作起来很有魅力。谢谢你的帮助!