Closing an anonymous delegate (or why does this work)?

The code below is taken directly from the sample project accompanying the article on MSDN, which represents the MVVM design pattern . I don’t quite understand why the delegate sees a “handler” value other than zero. I realized that the closure created for the delegate method contains all the variables in the scope that were initialized before this execution point, and since the “handler” is reassigned after the delegate was created, the closure will contain the “handler” set to null.

Konstantin


EventHandler handler = null;
handler = delegate
{
    viewModel.RequestClose -= handler;
    window.Close();
};
viewModel.RequestClose += handler;
+3
source share
4 answers

handler, .


, , # , , Reflector. :

class MyAnonymousDelegate
{
    public ... viewModel;
    public ... window;
    public EventHandler handler;

    public void DoIt(object sender, EventArgs e)
    {
        this.viewModel.RequestClose -= this.handler;
        this.window.Close();
    }
}

var mad = new MyAnonymousDelegate();
mad.viewModel = viewModel;
mad.window = window;
mad.handler = null;

mad.handler = new EventHandler(mad.DoIt);

viewModel.RequestClose += mad.handler;
+4

:

EventHandler handler = delegate
{
    viewModel.RequestClose -= handler;
    window.Close();
};
viewModel.RequestClose += handler;

CS0165: 'handler'.

, . , , , "". #. .

+2

, . , .

+1

:

       static void Main(string[] args)
    {

        EventHandler handler = null;

        handler = delegate
        {
            AppDomain.CurrentDomain.ProcessExit -= handler;

        };
        AppDomain.CurrentDomain.ProcessExit += handler;
    }

:

.method private hidebysig static void  Main(string[] args) cil managed
{
   .entrypoint
   // Code size       51 (0x33)
   .maxstack  4
   .locals init ([0] class ConsoleApplication1.Program/'c__DisplayClass1'    'CS$8__locals2')
   IL_0000:  newobj     instance void    ConsoleApplication1.Program/'c__DisplayClass1'::.ctor()
   IL_0005:  stloc.0
  IL_0006:  nop
  IL_0007:  ldloc.0
  IL_0008:  ldnull
  IL_0009:  stfld      class [mscorlib]System.EventHandler ConsoleApplication1.Program/'c__DisplayClass1'::'handler'
  IL_000e:  ldloc.0
  IL_000f:  ldloc.0
  IL_0010:  ldftn      instance void ConsoleApplication1.Program/'c__DisplayClass1'::'b__0'(object,
                                                                                                    class [mscorlib]System.EventArgs)
  IL_0016:  newobj     instance void [mscorlib]System.EventHandler::.ctor(object,
                                                                          native int)
  IL_001b:  stfld      class [mscorlib]System.EventHandler ConsoleApplication1.Program/'c__DisplayClass1'::'handler'
  IL_0020:  call       class [mscorlib]System.AppDomain [mscorlib]System.AppDomain::get_CurrentDomain()
  IL_0025:  ldloc.0
  IL_0026:  ldfld      class [mscorlib]System.EventHandler ConsoleApplication1.Program/'c__DisplayClass1'::'handler'
  IL_002b:  callvirt   instance void [mscorlib]System.AppDomain::add_ProcessExit(class [mscorlib]System.EventHandler)
  IL_0030:  nop
  IL_0031:  nop
  IL_0032:  ret
} // end of method Program::Main
+1

Source: https://habr.com/ru/post/1765531/


All Articles