https://www.youtube.com/watch?v=oWoclcZhcUQ&list=PLO56HZSjrPTB4NxAsEP8HRk6YKBDLbp7m&index=69


using System;
using static System.Console;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
namespace testProject
{
    
    class Car
    {
        // 특성(어노테이션), 더 이상 사용하지 않는 프로그램 요소를 표시, 상속 X
        [Obsolete("다음 버전에 제거될 예정이니 Auto()를 사용하세요.")] 
        public void Manual() => WriteLine("수동 운전");
        public void Auto() => WriteLine("자동 운전");
    }
    class Program
    {
        static void Main(string[] args)
        {
            Car car = new Car();
            car.Manual();
            car.Auto();
        }
    }
}

using System;
using static System.Console;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
namespace testProject
{
    
    class Car
    {
        // 특성(어노테이션), 더 이상 사용하지 않는 프로그램 요소를 표시, 상속 X
        [Obsolete("다음 버전에 제거될 예정이니 Auto()를 사용하세요.")] 
        public void Manual() => WriteLine("수동 운전");
        public void Auto() => WriteLine("자동 운전");
        // 둘 중 하나가 무시 되거나 다른 형식에 적용 하는 경우 컴파일러 경고 또는 오류 메시지가 생성
        [Conditional("DEBUG")]
        public void Test() => WriteLine("테스트 운전");
    }
    class Program
    {
        static void Main(string[] args)
        {
            Car car = new Car();
            car.Manual();
            car.Auto();
            car.Test();
        }
    }
}





#define RELEASE
using System;
using static System.Console;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
namespace testProject
{
    public class LuxuryAttribute : Attribute {
        public LuxuryAttribute() => WriteLine("럭셔리!!!");
    }
    // [LuxuryAttribute]
    [Luxury]
    class Car
    {
        // 더 이상 사용하지 않는 프로그램 요소를 표시, 상속 X
        [Obsolete("다음 버전에 제거될 예정이니 Auto()를 사용하세요.")] 
        public void Manual() => WriteLine("수동 운전");
        public void Auto() => WriteLine("자동 운전");
        // 둘 중 하나가 무시 되거나 다른 형식에 적용 하는 경우 컴파일러 경고 또는 오류 메시지가 생성
        [Conditional("DEBUG")]
        public void Test() => WriteLine("테스트 운전1");
        [Conditional("RELEASE")]
        public void Test2() => WriteLine("테스트 운전2");
    }
    class Program
    {
        static void Main(string[] args)
        {
            Car car = new Car();
            car.Manual();
            car.Auto();
            car.Test();
            car.Test2();
        }
    }
}


#define RELEASE
using System;
using static System.Console;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
namespace testProject
{
    public class LuxuryAttribute : Attribute {
        public LuxuryAttribute() => WriteLine("럭셔리!!!");
    }
    // [LuxuryAttribute]
    [Luxury]
    class Car
    {
        // 더 이상 사용하지 않는 프로그램 요소를 표시, 상속 X
        [Obsolete("다음 버전에 제거될 예정이니 Auto()를 사용하세요.")] 
        public void Manual() => WriteLine("수동 운전");
        public void Auto() => WriteLine("자동 운전");
        // 둘 중 하나가 무시 되거나 다른 형식에 적용 하는 경우 컴파일러 경고 또는 오류 메시지가 생성
        [Conditional("DEBUG")]
        public void Test() => WriteLine("테스트 운전1");
        [Conditional("RELEASE")]
        public void Test2() => WriteLine("테스트 운전2");
    }
    class Program
    {
        static void Main(string[] args)
        {
            Car car = new Car();
            // 리플렉션, 특정한 클래스에 정의된 특성을 읽어온다
            Attribute.GetCustomAttributes(typeof(Car));
            typeof(Car).GetCustomAttributes(false);
            car.Manual();
            car.Auto();
            car.Test();
            car.Test2();
        }
    }
}


#define RELEASE
using System;
using static System.Console;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.Reflection;
namespace testProject
{
    public class LuxuryAttribute : Attribute {
        public LuxuryAttribute() => WriteLine("럭셔리!!!");
    }
    // [LuxuryAttribute]
    [Luxury]
    class Car
    {
        // 더 이상 사용하지 않는 프로그램 요소를 표시, 상속 X
        [Obsolete("다음 버전에 제거될 예정이니 Auto()를 사용하세요.")] 
        public void Manual() => WriteLine("수동 운전");
        public void Auto() => WriteLine("자동 운전");
        // 둘 중 하나가 무시 되거나 다른 형식에 적용 하는 경우 컴파일러 경고 또는 오류 메시지가 생성
        [Conditional("DEBUG")]
        public void Test() => WriteLine("테스트 운전1");
        [Conditional("RELEASE")]
        public void Test2() => WriteLine("테스트 운전2");
    }
    class Program
    {
        static void Main(string[] args)
        {
            Car car = new Car();
            // 리플렉션, 특정한 클래스에 정의된 특성을 읽어온다
            Attribute.GetCustomAttributes(typeof(Car));
            typeof(Car).GetCustomAttributes(false);
            car.Manual();
            car.Auto();
            car.Test();
            car.Test2();
            // 리플렉션, 모든 클래스, 모든 구조체, 모든 열거형 ...을 다읽어올 수 있는 메서드 제공
            Car carType = new Car();
            Type myCar = carType.GetType();
            MethodInfo info =  myCar.GetMethod("Auto");
            info.Invoke(carType, null);
        }
    }
}
