Pergunta

Não tenho certeza do que exatamente está acontecendo aqui, mas parece que no .NET 1.1, um delegado de evento não inicializado pode ser executado sem problemas, mas no .NET 2.0+ causa uma NullReferenceException. Qualquer idéia por quê. O código abaixo será bom sem problemas em 1.1, em 2.0, fornece uma NullReferenceException. Estou curioso para saber por que isso se comporta de maneira diferente? O que mudou?

Obrigado

por exemplo

class Class1
    {
    public delegate void ChartJoinedRowAddedHandler(object sender);



    public static event ChartJoinedRowAddedHandler ChartJoinedRowAdded;
    public static DataTable dt;

    public static void Main()
    {           
        dt = new DataTable();
        dt.RowChanged += new DataRowChangeEventHandler(TableEventHandler);

        object [] obj = new object[]{1,2};
        dt.Columns.Add("Name");
        dt.Columns.Add("Last");
        dt.NewRow();
        dt.Rows.Add(obj);
    }

    private static void TableEventHandler(object sender, DataRowChangeEventArgs e)
    {
        ChartJoinedRowAdded(new object());
    }
}
Foi útil?

Solução

Atualizado] Afaik, não houve mudança aqui para o manuseio fundamental dos delegados; A diferença está em como o Datatable se comporta.

No entanto! Tenha muito cuidado usando eventos estáticos, especialmente se você estiver se inscrevendo em instâncias (em vez de métodos estáticos). Esta é uma boa maneira de manter vidas enormes faixas de objetos e não ser coletado de lixo.

Executar o código via CSC de 1.1 mostra que o lado do delegado geral é o mesmo - acho que a diferença é que o código de dados que aumenta o Rowchanged estava engolindo a exceção. Por exemplo, faça o código como abaixo:

    Console.WriteLine("Before");
    ChartJoinedRowAdded(new object());
    Console.WriteLine("After");

Você verá "antes", mas não "depois"; Uma exceção foi lançada e engolida pelo Datatable.

Outras dicas

O sistema EventHandler é basicamente apenas uma lista de funções para ligar quando um determinado evento for criado.

Ele inicializa para a lista "nula", e não a lista vazia, então você precisa fazer

if (ChartJoinedRowAdded != null)
      ChartJoinedRowAdded(new object())

A maneira como os eventos funcionam realmente não mudou de 1,1 para 2

Embora a sintaxe pareça uma agregação normal, realmente não é:

dt.RowChanged += TableEventHandler;
dt.RowChanged += null;
dt.RowChanged += delegate (object sender, DataRowChangeEventArgs e) {
    //anon
};

Vai disparar TableEventHandler E então o delegado - o nulo é ignorado.

Você pode usar o NULL para limpar os eventos, mas apenas dentro da aula de disparo de eventos:

this.MyEvent = null;

Se nada assinar o seu evento será nulo - veja a resposta de Soraz. o DataTable A classe conterá uma verificação semelhante e não demitirá o evento se não houver assinantes.

O padrão padrão é:

//events should just about always use this pattern: object, args
public static event EventHandler<MyEventArgs> ChartJoinedRowAdded;


//inheriting classes can override this event behaviour
protected virtual OnChartJoinedRowAdded() {
    if( ChartJoinedRowAdded != null )
        ChartJoinedRowAdded( this, new MyEventArgs(...) );
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top