用于事件和绑定异常的一次性lambda

时间:2012-10-19 09:17:34

标签: c# .net events reflection lambda

我试图取消订阅本身的lambda。我使用MethodInfo类获取有关lambda的信息,使用Delegate.CreateDelegate方法创建与lambda相同的方法。因此,如果在包含我使用的事件的一个类方法中创建的lambda但在另一个类方法(绑定异常)中不起作用,则它可以正常工作。

以下是代码:

public class TestClass
{
    public event Action SomeEvent;
    public void OnSomeEvent()
    {
        if (SomeEvent != null)
        {
            SomeEvent();
        }
    }
    public TestClass()
    {
        //IT WORKS FINE!!!
        //SomeEvent += () =>
        //{
        //    Console.WriteLine("OneShotLambda");
        //    MethodInfo methodInfo = MethodInfo.GetCurrentMethod() as MethodInfo;
        //    Action action = (Action)Delegate.CreateDelegate(typeof(Action), this, methodInfo);
        //    SomeEvent -= action;
        //};
    }
}

class Program
{
    static void Main(string[] args)
    {
        TestClass t = new TestClass();
        t.SomeEvent += () =>
            {
                Console.WriteLine("OneShotLambda");
                MethodInfo methodInfo = MethodInfo.GetCurrentMethod() as MethodInfo;
                //GOT AN ERROR
                Action action = (Action)Delegate.CreateDelegate(typeof(Action), t, methodInfo);
                t.SomeEvent -= action;
            };
        t.OnSomeEvent();
        t.OnSomeEvent(); //MUST BE NO MESSAGE
    }
}

1 个答案:

答案 0 :(得分:6)

它不起作用的原因是,当您传递t时,将CreateDelegate作为第二个参数传递给null。这是因为为lambda创建的方法将是一个静态方法。否则无法从静态Main方法中使用它。并且documentation明确指出您需要为静态方法传递null

话虽如此,你最好不要这样做:

TestClass t = new TestClass();
Action eventHandler = null;
eventHandler = () =>
               {
                   Console.WriteLine("OneShotLambda");
                   t.SomeEvent -= eventHandler;
               }
t.SomeEvent += eventHandler;

此代码更具可读性和易懂性,并且性能更佳。