2012-10-19 20 views
0

我試圖從其內部取消訂閱lambda。我使用MethodInfo類獲取有關lambda的信息,並使用Delegate.CreateDelegate方法創建與lambda相同的方法。因此,如果在包含我使用的事件的類方法之一中創建的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 
    } 
} 
+0

http://stackoverflow.com/questions/5623658/single-shot-event-subscription – spender

回答

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; 

此代碼的可讀性和可理解的和額外的性能會更好。

+0

如果我傳遞null,那麼t.SomeEvent - = action不會從事件中移除當前的lambda,並且也沒有例外(很奇怪)。所以我會用你的解決方案。謝謝。 – shadeglare