Action <object,eventargs =“”>无法转换为EventHandler?</object,>

时间:2009-10-11 22:25:21

标签: c# .net event-handling casting

我正在连接一个事件以使用一个lambda,它需要在触发后自行移除。我无法通过将lambda内联到+ =事件(没有用于删除事件的可访问变量)来做到这一点,所以我设置了一个Action<object, EventArgs>变量并将lambda移动到那里。主要错误是它无法将Action<object, EventArgs>转换为EventHandler。我认为lambda表达式可以隐式转换为事件处理程序,为什么这不起作用?

5 个答案:

答案 0 :(得分:40)

Action<Object, EventArgs> a = (o, ea) => { };
EventHandler e = a.Invoke;

答案 1 :(得分:36)

Lambda可以隐式转换为具有正确形状的委托类型,但是两个相同形状的委托类型不能隐式地相互转换。只需让局部变量改为类型为EventHandler。

EventHandler h = (o, ea) => { ... };
e += h;
...
e -= h;

(如果有帮助:

Action<object, EventArgs> a = (o, ea) => { }; 
EventHandler e = a;  // not allowed
EventHandler e2 = (o,ea) => a(o,ea);  // ok

答案 2 :(得分:2)

通常,委托不能被强制转换,因为它们没有定义哪些强制转换有效的继承树。为此,您有两个选择:

  1. 使用EventHandler类型的变量代替Action<T1, T2>
  2. 使用内联声明。

    // option 1: local variable
    EventHandler eh = (o, ea) => { /* [snip] */ };
    obj.event += eh;
    obj.event -= eh;
    
    // option 2: inline declaration
    obj.event += (o, ea) => { /* [snip] */ };
    

答案 3 :(得分:1)

将您的活动声明为

public event Action<object, EventArgs> e;

然后你可以直接添加你的动作:

Action<object, EventArgs> a = something;
e += a;

答案 4 :(得分:0)

您可以使用匿名方法:

Event += (sender, e) =>
{
     // Multiple lines
     // of code here
};