Se mi registro per un evento in c # mentre è in corso l'invio, posso garantire di non essere più richiamato durante tale invio?

StackOverflow https://stackoverflow.com/questions/141423

  •  02-07-2019
  •  | 
  •  

Domanda

In C #, mi trovo di tanto in tanto a voler registrare un metodo per un evento nel mezzo di una spedizione dello stesso evento. Ad esempio, se ho una classe che transita gli stati in base ai successivi invii dello stesso evento, potrei volere che il gestore del primo stato si annulli la registrazione e registri il secondo gestore. Tuttavia, non desidero che il secondo gestore venga spedito fino alla successiva attivazione dell'evento.

La buona notizia è che sembra che l'implementazione Microsoft di C # si comporti esattamente in questo modo. Lo zucchero della sintassi di registrazione dell'evento viene sostituito con una chiamata a System.Delegate.Combine, che concatena semplicemente l'elenco di invocazioni corrente e il nuovo metodo in un elenco separato e lo assegna alla proprietà dell'evento. Questo mi dà esattamente il comportamento che desidero.

Quindi, la mia domanda è: questo comportamento è garantito dallo standard linguistico? Mi piace essere in grado di eseguire il mio codice C # su altre piattaforme in modalità mono e in genere voglio assicurarmi di non fare ipotesi sullo standard linguistico in base alla sua implementazione.

Non sono riuscito a trovare informazioni definitive su MSDN.

Se desideri un esempio specifico di ciò di cui sto parlando, ecco un esempio:

    delegate void TestDelegate();
    static event TestDelegate TestEvent;

    static void Main (string[] args) {
        TestEvent += TestDelegateInstanceFirst;
        TestEvent();
        TestEvent();
    }

    static void TestDelegateInstanceFirst () {
        Console.WriteLine("First");
        TestEvent += TestDelegateInstanceSecond;
    }

    static void TestDelegateInstanceSecond () {
        Console.WriteLine("Second");
    }

Almeno su Windows, l'output è:

First
First
Second
È stato utile?

Soluzione

Sì, è garantito.

Dalle specifiche unificate di C # 3.0, sezione 15.1:

  

Tuttavia, quando due delegati non nulli   le istanze sono combinate, loro   gli elenchi di invocazioni sono concatenati & # 8212; in   l'ordine operando a sinistra quindi a destra   operando & # 8212; per formare un nuovo elenco di invocazioni,   che contiene due o più voci.

Nota il " nuovo elenco di invocazioni " ;. E ancora nella sezione 15.3:

  

Una volta istanziati, delegare le istanze   fare sempre riferimento allo stesso oggetto target   e metodo. Ricorda, quando due   i delegati sono combinati o uno è   rimosso da un altro, un nuovo delegato   risulta con un proprio elenco di invocazioni;   gli elenchi di invocazione dei delegati   combinati o rimossi rimangono invariati.

Infine, MSDN per System.Delegate afferma:

  

I delegati sono immutabili; una volta creato,   fa l'elenco di invocazione di un delegato   non cambiare.

Sospetto che ci sia qualcosa nelle specifiche della CLI: controllerò se vuoi, ma spero che questi tre ti abbiano dato abbastanza sicurezza :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top