Since we register the callback function PrintOne twice, the following code will print the message “PrintOne” twice. Here are questions,
Question 1> Why by default the operator+=(i.e. Combine) doesn’t check duplicate method handler?
Question 2> How to avoid this duplicated call in method RegisterCall? I try to find some method in MulticastDelegate/Delegate that can tell me there is already one in the calling list. But I didn’t find it.
http://msdn.microsoft.com/en-us/library/system.multicastdelegate.aspx
Thank you
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace app3
{
class Car
{
public delegate void PrintMethod(string msg);
public string Name { get; set; }
private PrintMethod printMethods;
public Car() { }
public Car(string name) { Name = name; }
public void PrintCar()
{
if (printMethods != null)
{
printMethods(this.ToString());
}
else
{
Console.WriteLine("No Method will be called");
}
}
public override string ToString()
{
return string.Format("Car Name is {0}: ", Name);
}
public static void PrintOne(string msg)
{
Console.WriteLine("PrintOne");
}
public static void PrintTwo(string msg)
{
Console.WriteLine("PrintTwo");
}
public void RegisterCall(PrintMethod methodToCall)
{
printMethods += methodToCall;
}
}
class Program
{
static void Main(string[] args)
{
Car mycar = new Car { Name = "BMW" };
mycar.RegisterCall(new Car.PrintMethod(Car.PrintOne)); // **will print for the first time**
mycar.RegisterCall(new Car.PrintMethod(Car.PrintOne)); // **will print for the second time**
mycar.PrintCar();
Console.ReadLine();
}
}
}
This will make sure it is removed if present in the multicast delegate, then added, to ensure 1 instance.
Adding a handler doesn’t abort if a delegate to the same handler is already present in the multicast delegate because most of the time duplicates don’t happen. There are also valid situations in which calling the same method twice is what is wanted (such as custom aggregation on an object or collection).
If they had decided that duplication would be avoided, they would have to throw an exception when adding the handler. That’s expensive in a number of ways, both when they occur at runtime and in all the ugly
try-catchblocks we’d have to write.