//
// 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;
using System.Reflection;

namespace DelegatesAndEvents
{
	class DelegateClass
	{
		public void HelloWorldProcessor(string message)
		{
			Console.WriteLine("DelegateClass: {0}", message);
		}
		public void A(string message)
		{
			Console.WriteLine("A: {0}", message);
		}
		public void B(string message)
		{
			Console.WriteLine("B: {0}", message);
		}
		public void C(string message)
		{
			Console.WriteLine("C: {0}", message);
		}
	}
	class HelloWorld
	{
		// static private int HelloWorldProcessor(string message)
		static private void HelloWorldProcessor(string message)
		{
			Console.WriteLine(message);
		}
		public delegate void HelloWorldDelegate(string message);
		static void Main(string[] args)
		{
			HelloWorldDelegate d = new HelloWorldDelegate(HelloWorldProcessor);
			d("Witaj świecie!");

			Console.WriteLine("Metoda: {0}", d.Method);
			Console.WriteLine("Cel: {0}", d.Target);

			DelegateClass dc = new DelegateClass();
			d = new HelloWorldDelegate(dc.HelloWorldProcessor);
			d("Witaj świecie!");
			IAsyncResult ar = d.BeginInvoke("Wywołano Witaj świecie!", null, null);

			Console.WriteLine("Method: {0}", d.Method);
			Console.WriteLine("Target: {0}", d.Target);

			d.EndInvoke(ar);

			d = new HelloWorldDelegate(HelloWorldProcessor);
			d += new HelloWorldDelegate(dc.HelloWorldProcessor);
			d += new HelloWorldDelegate(dc.A);
			d += new HelloWorldDelegate(dc.B);
			d += new HelloWorldDelegate(dc.C);
			d("Witaj świecie! z wielokrotnym rzutowaniem");

			Console.WriteLine("Metoda: {0}", d.Method);
			Console.WriteLine("Cel: {0}", d.Target);

			Delegate [] list = d.GetInvocationList();
			foreach(Delegate item in list)
			{
				Console.WriteLine("Metoda: {0}", item.Method);
				Console.WriteLine("Cel: {0}", item.Target);
			}

			Type t = dc.GetType();
			MethodInfo mi = t.GetMethod("HelloWorldProcessor");
			ParameterInfo[] pia = mi.GetParameters();
			foreach(ParameterInfo pi in pia)
			{
				Console.WriteLine(pi.ParameterType);
			}

			d = (HelloWorldDelegate)Delegate.CreateDelegate(typeof(HelloWorldDelegate), dc, "HelloWorldProcessor"); 
			d.DynamicInvoke(new object [] {"Witaj świecie! z późnym wiązaniem"});
			d = (HelloWorldDelegate)Delegate.CreateDelegate(typeof(HelloWorldDelegate), typeof(HelloWorld), "HelloWorldProcessor"); 
			d.DynamicInvoke(new object [] {"Statyczne Witaj świecie! z późnym wiązaniem"});

		}
	}
}
