Removing delegates

Now that you have some understanding of how delegates are compared, you can move on to how delegates are removed from a delegate chain. A delegate chain is simply an array of delegates. To remove a delegate from the chain, the chain is traversed and the first delegate that equals the delegate passed as an argument to Remove will be removed. Some examples best illustrate the concepts regarding delegate removal. The full source code for the code illustrated in Listings 14.1514.17 is in the DelegateRemoval directory.

Listing 14.15. Listing delegates in a delegate Chain
DelegateCallback ad = new DelegateCallback(ACallback);
DelegateCallback bd = new DelegateCallback(BCallback);
DelegateCallback cd = new DelegateCallback(CCallback);

DelegateCallback dd = ad;
dd += bd;
dd += cd;

Delegate [] da = dd.GetInvocationList();
foreach(Delegate d in da)
{
    Console.WriteLine("{0}  {1} ", d.Target, d.Method);
}

Listing 14.15 simply shows the process of building a delegate chain and then retrieving the contents. Notice that because you are using static callbacks, the Target property is null for each of the delegates. Listing 14.16 shows the removal of a single delegate from the list.

Listing 14.16. Removing a delegate from a delegate Chain
dd = (DelegateCallback)Delegate.Remove(dd, cd);
da = dd.GetInvocationList();
foreach(Delegate d in da)
{
    Console.WriteLine("{0}  {1} ", d.Target, d.Method);
}

Here the chain is searched for the cd delegate and it is removed. A delegate chain is immutable, much like many of the objects within the .NET Framework (string being a prime example). Because of this immutability, a new delegate chain is constructed and returned from the Remove method. The listing will show all but the cd delegate in the chain. Listing 14.17 shows the effect of placing duplicate delegates in a chain.

Listing 14.17. Removing Duplicates from a delegate Chain
dd += cd;
dd += cd;
dd = (DelegateCallback)Delegate.Remove(dd, cd);
da = dd.GetInvocationList();
foreach(Delegate d in da)
{
    Console.WriteLine("{0}  {1} ", d.Target, d.Method);
}

The output on the Console will show that only one of the cd delegates in the chain is removed. The chain is searched until either a match is found (the delegate is equal) or the end of the chain is reached. If a match is found, then processing is terminated. Duplicates are not removed—just the first delegate found. A workaround for this problem is presented in Listing 14.18.

Listing 14.18. Removing a Chain from a delegate Chain
Console.WriteLine("Merging a chain on the list");
DelegateCallback ed = cd;
ed += cd;
dd += ed;
da = dd.GetInvocationList();
foreach(Delegate d in da)
{
    Console.WriteLine("{0}  {1} ", d.Target, d.Method);
}
Console.WriteLine("Removing a chain from the list");
dd = (DelegateCallback)Delegate.Remove(dd, ed);
da = dd.GetInvocationList();
foreach(Delegate d in da)
{
    Console.WriteLine("{0}  {1} ", d.Target, d.Method);
}

This code snippet first merges two chains to form one chain. The delegate that is specified to be removed is actually a chain, too; therefore, when that chain is found in the delegate chain, the entire chain is removed. In this case, both duplicate and delegates are removed.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.139.50