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

sha*_*are 0 .net c# reflection events 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
    }
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*rth 6

它不起作用的原因是你t作为第二个参数CreateDelegate传入你应该传递的时间null.这是因为为lambda创建的方法将是一个静态方法.否则无法从静态Main方法中使用它.而文件中明确指出,你需要通过null静态方法.

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

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

此代码更具可读性和可理解性,并且性能更佳.