//
// Copyright (c) 2002
// Ronald Kevin Burton
//
// Z poniższym kodem nie jest związana żadna gwarancja poprawności działania.
// Program został dołączony do książki ".NET CLR. Księga eksperta" w celu
// ilustracji koncepcji i zasad przedstawionych w tej książce. Program może być 
// używany na własne ryzyko.
//
// Przyznaje się prawo do użycia lub kopiowania tego oprogramowania do dowolnego celu
// bez konieczności ponoszenia żadnych opłat pod warunkiem, że powyższe uwagi zostaną 
// zachowane we wszystkich kopiach. Przyznaje się także prawo do modyfikacji kodu
// i dystrybucji zmodyfikowanego kodu pod warunkiem zachowania powyższych uwag
// oraz dołączenia informacji mówiącej o modyfikacji kodu.
//
//  
using System;

namespace DelegatesAndEvents
{
	delegate void DelegateCallback();
	class A
	{
		public void ACallback()
		{
			Console.WriteLine("A.ACallback()");
		}
		public void BCallback()
		{
			Console.WriteLine("A.BCallback()");
		}
		public void CCallback()
		{
			Console.WriteLine("A.CCallback()");
		}
	}
	class B
	{
		public void ACallback()
		{
			Console.WriteLine("B.ACallback()");
		}
		public void BCallback()
		{
			Console.WriteLine("B.BCallback()");
		}
		public void CCallback()
		{
			Console.WriteLine("B.CCallback()");
		}
	}
	class C
	{
		public void ACallback()
		{
			Console.WriteLine("C.ACallback()");
		}
		public void BCallback()
		{
			Console.WriteLine("C.BCallback()");
		}
		public void CCallback()
		{
			Console.WriteLine("C.CCallback()");
		}
	}
	class DelegateEquality
	{
		static void ACallback()
		{
			Console.WriteLine("ACallback()");
		}
		static void BCallback()
		{
			Console.WriteLine("BCallback()");
		}
		static void CCallback()
		{
			Console.WriteLine("CCallback()");
		}
		static void Main(string[] args)
		{
			DelegateCallback ad = new DelegateCallback(ACallback);
			DelegateCallback bd = new DelegateCallback(BCallback);
			DelegateCallback cd = new DelegateCallback(ACallback);
			Console.WriteLine("static {0} == {1} {2}", ad.Method, bd.Method, ad == bd);
			Console.WriteLine("static {0} == {1} {2}", ad.Method, ad.Method, ad == ad);
			Console.WriteLine("static {0} == {1} {2}", ad.Method, cd.Method, ad == cd);
			
			A a1 = new A();
			B b1 = new B();
			C c1 = new C();

			ad = new DelegateCallback(a1.ACallback);
			bd = new DelegateCallback(a1.BCallback);
			Console.WriteLine("egzemplarz {0}.{1} == {2}.{3} {4}", ad.Target, ad.Method, bd.Target, bd.Method, ad == bd);
			cd = new DelegateCallback(a1.ACallback);
			Console.WriteLine("egzemplarz {0}.{1} == {2}.{3} {4}", ad.Target, ad.Method, cd.Target, cd.Method, ad == cd);
			
			A a2 = new A();

			bd = new DelegateCallback(a2.ACallback);
			Console.WriteLine("egzemplarz {0}.{1} == {2}.{3} {4}",  ad.Target, ad.Method, bd.Target, bd.Method, ad == bd);

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

			DelegateCallback ed = ad;
			ed += bd;
			ed += cd;
			Console.WriteLine("łańcuch {0} == {1} {2}", dd.Method, ed.Method, dd == ed);

			ed = cd;
			ed += bd;
			ed += ad;
			Console.WriteLine("łańcuch {0} == {1} {2}", dd.Method, ed.Method, dd == ed);
		}
	}
}
