I have written a very simple console test application in C# (attached below) with an Event and an Event handler. The Event handler is registered and unregistered using several ways.
As far as I've understood, the following two expressions result in the same:
Event1 += handler;
Event1 += new TestEventHandler(handler);
Now I principally expected the same for these two expressions:
Event1 -= handler;
Event1 -= new TestEventHandler(handler);
I relied on the handler being unregistered in both cases. But it seems that there is a difference: It's only different, when I pass the event handler as parameter to a method, then the handler gets not unregistered for the case when the code in the method is implemented using -= new TestEventHandler(handler). However, it works if the code is using -= handler directly.
I don't understand it. Why is this?
Now follows the whole code (you can copy and paste it directly to Visual Studio), and below you find the output that I got:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EventDemo1
{
class Program
{
static void Main(string[] args)
{
Test test = new Test();
test.Run();
Console.ReadLine();
}
}
class TestEventArgs : System.EventArgs
{
public TestEventArgs() { }
public TestEventArgs(int no) { No = no; }
public int No;
}
delegate void TestEventHandler(TestEventArgs e);
public class Test
{
public Test()
{
}
void TestHandler(TestEventArgs e)
{
Console.WriteLine("No={0}", e.No);
}
event TestEventHandler Event1;
public void Run()
{
Console.WriteLine("START");
Event1 += TestHandler;
if (Event1 != null)
Event1(new TestEventArgs(1)); //1
Event1 -= TestHandler; // Uses: Event1 -= TestHandler;
if (Event1 != null)
Event1(new TestEventArgs(2)); //2
Console.WriteLine("---------- OK. (Event1 == null) is {0}.", Event1 == null);
Console.WriteLine("START");
Event1 += new TestEventHandler(TestHandler);
if (Event1 != null)
Event1(new TestEventArgs(3)); //3
Event1 -= new TestEventHandler(TestHandler); // Uses: Event1 -= new TestEventHandler(TestHandler);
if (Event1 != null)
Event1(new TestEventArgs(4)); //4
Console.WriteLine("---------- OK. (Event1 == null) is {0}.", Event1 == null);
Console.WriteLine("START using Register1/Unregister1");
RegisterHandler1(TestHandler);
if (Event1 != null)
Event1(new TestEventArgs(5)); //5
UnregisterHandler1(TestHandler); // Uses: Event1 -= TestHandler; where TestHandler is used directly.
if (Event1 != null)
Event1(new TestEventArgs(6)); //6
Console.WriteLine("---------- OK. (Event1 == null) is {0}.", Event1 == null);
Console.WriteLine("START using Register2/Unregister2");
RegisterHandler2(TestHandler);
if (Event1 != null)
Event1(new TestEventArgs(7)); //7
UnregisterHandler2(TestHandler); // Uses: Event1 -= new TestEventHandler(handler); where handler was passed as parameter
if (Event1 != null)
Event1(new TestEventArgs(8)); //8
Console.WriteLine("---------- Not OK. (Event1 == null) is {0}.", Event1 == null);
Console.WriteLine(" I expected that number 8 should not occur, but it does.");
Console.WriteLine("END.");
}
private void RegisterHandler1(TestEventHandler handler)
{
Event1 += handler;
}
private void UnregisterHandler1(TestEventHandler handler)
{
Event1 -= handler;
}
private void RegisterHandler2(TestEventHandler handler)
{
Event1 += new TestEventHandler(handler);
}
private void UnregisterHandler2(TestEventHandler handler)
{
Event1 -= new TestEventHandler(handler);
}
}
}
the output:
START
No=1
---------- OK. (Event1 == null) is True.
START
No=3
---------- OK. (Event1 == null) is True.
START using Register1/Unregister1
No=5
---------- OK. (Event1 == null) is True.
START using Register2/Unregister2
No=7
No=8
---------- Not OK. (Event1 == null) is False.
I expected that number 8 should not occur, but it does.
END.