using System;
using System.Reflection;    // c#의 reflect 서비스
// Reflection 메타데이타 에서 정보를 얻어온다.
class Point
{
    public int x;
    public int y;
    public void foo() { }
}
class Test
{
    public static void Main()
    {
        Point p = new Point();
        Type t = p.GetType();   // p의 type 정보를 담고 있는 객체를 얻는다.
                                // RTTI, RTCI(MFC)
        Console.WriteLine("{0}", t.FullName);
        Console.WriteLine("{0}", t.BaseType.FullName);
        // t의 모든 메소드 정보를 배열로 얻어 온다.
        MethodInfo[] mis = t.GetMethods();
        // 배열의 모든 요소를 열거하면서 출력한다.
        foreach (MethodInfo m in mis)
        {
            Console.WriteLine("{0}, {1}", m.Name, m.ReturnType);
        }
    }
}
// Monostate : static 멤버 data와 static 멤버 변수만 가진 클래스 객체를
만들 필요가 없다.
class Math
{
    //private Math() { }
    public static int plus(int a, int b) { return a + b; }
}
Math.plus(1, 2);
///////////////////////////////////////////////////////////////////////////
// 델리게이트 선언
delegate void CrashHandler( int a );
// 위 선언을 보고 C#컴파일러가 CrashHandler라는 클래스를 생성해 준다.
// 내부적으로 void를 리턴하고 int 인자가 1개인 함수 포인터를 관리해주는 클래스.
class Car
{
    public int speed = 0;
    public CrashHandler handler;    // 델리게이터의 참조
    public void SetSpeed(int n)
    {
        speed = n;
        if (handler != null)
            handler.Invoke(n);  //handler(n);  // 외부에 알린다.
    }
}
class Test
{
    public static void foo(int a)
    {
        Console.WriteLine("Test::foo - {0}", a);
    }
    public static void Main()
    {
        Car c = new Car();
        c.handler = new CrashHandler(Test.foo);
        c.handler += new CrashHandler(Test.foo);
    }
}
