0

それ自体でラムダからサブスクライブを解除しようとしました。MethodInfo クラスを使用してラムダに関する情報を取得し、Delegate.CreateDelegate メソッドを使用してラムダと同じメソッドを作成しました。そのため、使用するイベントを含むクラス メソッドの 1 つで作成されたラムダが、別のクラス メソッド (バインディング例外) では機能しない場合は正常に機能します。

コードは次のとおりです。

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
    }
}
4

1 に答える 1

6

それが機能しない理由はt、2 番目のパラメーターとしてCreateDelegatewhen you should pass に渡すためnullです。これは、ラムダ用に作成されたメソッドが静的メソッドになるためです。そうしないと、静的Mainメソッドから使​​用できませんでした。また、ドキュメントnullには、静的メソッドを渡す必要があることが明確に記載されています。

そうは言っても、別の方法で行う方がよいでしょう:

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

このコードは読みやすく理解しやすく、さらにパフォーマンスが向上します。

于 2012-10-19T09:21:07.937 に答える