Se eu registrar para um evento em c # enquanto ele está despachando, estou garantida para não ficar chamado novamente, durante a expedição?

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

  •  02-07-2019
  •  | 
  •  

Pergunta

Em C #, eu me encontro de vez em quando querendo registrar um método para um evento no meio de uma expedição desse mesmo evento. Por exemplo, se eu tiver uma classe que estados de transição com base em despachos sucessivos do mesmo evento, eu poderia querer manipulador do primeiro estado para cancelar o registro próprio e registrar o segundo manipulador. No entanto, eu não quero o segundo manipulador para ser despachado até a próxima vez que o evento é acionado.

A boa notícia é que parece que a implementação da Microsoft C # se comporta exatamente dessa forma. açúcar o registro do evento sintaxe é substituído com uma chamada para System.Delegate.Combine, que apenas concatena a lista de invocação atual e o novo método em uma lista e atribui à propriedade de evento separado. Isso me dá exatamente o comportamento Quero.

Assim, a minha pergunta é: é esse comportamento pelo padrão de linguagem garantida? Eu gosto de ser capaz de executar o meu código C # em outras plataformas sob mono e geralmente querem ter certeza que eu não estou fazendo suposições sobre o padrão de linguagem com base em sua implementação.

Eu não poderia encontrar qualquer informação definitiva sobre MSDN.

Se você gostaria de um exemplo específico do que eu estou falando, aqui está um exemplo:

    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");
    }

Pelo menos no Windows, a saída é:

First
First
Second
Foi útil?

Solução

Sim, é garantido.

A partir do C # 3.0 especificação unificada, seção 15.1:

No entanto, quando dois delegado não nulo exemplos são combinados, o seu listas de invocação são concatenados-in a ordem deixada operando depois à direita operando para formar uma nova lista de invocação, que contém dois ou mais entradas.

Observe a "nova lista de invocação". E mais uma vez na seção 15.3:

Uma vez instanciado, delegado instâncias referem-se sempre para o mesmo objecto alvo e método. Lembre-se, quando dois delegados são combinados, ou um é removido do outro, um novo delegado resultados com a sua própria lista de invocação; as listas de invocação dos delegados combinada ou removido permanecem inalterados.

Finalmente, MSDN para System.Delegate afirma

Os delegados são imutáveis; uma vez criado, a lista de invocação de um delegado faz Não mudança.

Eu suspeito que há algo na especificação CLI - Vou verificar se você gostaria, mas espero que estes três deram-lhe confiança suficiente:)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top