C# - Reflection & Attributes) 복습을 위해 작성하는 글 2023-04-30

rizz·2023년 4월 30일
0

C

목록 보기
13/25

📒 갈무리 - Reflection & Attributes

📌 Reflection이란?

- 프로그램 실행 중에 객체의 정보를 얻거나, 다른 모듈에 선언된 인스턴스를 생성하거나, 기존 개체에서 형식을 가져오고 해당하는 메소드를 호출, 또는 해당 필드와 속성에 접근할 수 있는 기능을 제공한다.

- 인 게임에서 사용하기보다, 툴이나 에디터 상에서 데이터 처리할 때 사용

 

📌 GetType & typeof

GetType : 런타임 시점의 Object를 상속받는 객체 인스턴스의 Type을 알려준다.

typeof : 컴파일 시점의 클래스 자체의 Type을 알려준다.

 

📌 Reflection 예제

// C#

 	class MyClass
    {
        public string Name { get; set; }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            MyClass myClass = new MyClass();
            SetDefaultName(myClass);
            Console.WriteLine("MyClass Name : " + myClass.Name);
        }
        
        static void SetDefaultName(Object myObject)
        {
            // Name이라는 Property가 있는지?
            // 없으면 null
            // method를 확인하고 싶다면 MethodInfo
            // field를 확인하고 싶다면 FieldInfo
            PropertyInfo propertyInfo = myObject.GetType().GetProperty("Name");

            // Name이라는 Property가 있으면 값 설정
            if (propertyInfo != null)
            {
                // SetValue 요약:
                //     지정된 개체의 속성 값을 설정합니다.
                //
                // 매개 변수:
                //   obj:
                //     속성 값이 설정될 개체입니다.
                //
                //   value:
                //     새 속성 값입니다.
                propertyInfo.SetValue(myObject, "Kim");

                // 메소드는 Invoke함수 사용
            }
        }
    }
    
Output:
MyClass Name : Kim

 

📌 클래스 정보 얻어오기

// C#
	
    class Class1
    {
        public void Run()
        {
            // 네임스페이스.클래스명
            // Type을 얻어옴
            Type customerType = Type.GetType("MyNamespace.Customer");

            // Type으로부터 클래스 객체 생성
            // 기존에는 new로 instance를 생성했었다면 Reflection할 때는 Activator로 Instance 생성
            Object obj = Activator.CreateInstance(customerType);

            // obj를 Customer로 캐스팅 후 Name에 접근
            string name = ((Customer)obj).Name;
            Console.WriteLine(name);
        }
    }

    public class Customer
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public Customer()
        {
            this.Name = "None";
        }
    }

 

📌 Attributes란?

- 메타데이터를 추가할 수 있는 기능을 제공한다.

- 클래스, 메소드, 구조체, 생성자, 프로퍼티, 필드, 이벤트, 인터페이스 등 여러 가지 요소에 Attributes를 사용할 수 있다.

- 주석은 개발자가 참고하기 위해 사용하는 것이며 런타임 때는 전혀 고려되지 않지만, Attributes는 컴퓨터가 런타임에 참고하기 위해 사용되는 주석과 같은 존재이며 컴퓨터가 런타임 중에도 Attributes가 붙은 대상을 체크하여 그에 관한 작업을 진행한다.

- 특성을 찾고 작업을 수행하는 것은 모두 C# 컴파일러가 진행한다.

 

📌 메타데이터란? (Metadata)

- 코드에 대한 정보 혹은 데이터를 말한다.

 

📌 Attributes 예제

// C#

	public class AttributesEX
    {
    	// Attributes
    	[Obsolete("이 메소드는 더 이상 사용되지 않습니다.")]
        public static int Add(int a, int b)
        {
        	return (a + b);
        }
	}

사용자 지정 Attributes

    // Attribute를 상속받음
    class DeveloperAttribute : Attribute
    {
        private string name;
        private string level;
        private bool reviewed;

        public DeveloperAttribute(string name, string level)
        {
            this.name = name;
            this.level = level;
            this.reviewed = false;
        }

        public virtual string Name
        {
            get { return name; }
        }

        public virtual string Level
        {
            get { return level; }
        }

        public virtual bool Reviewed
        {
            get { return reviewed; }
            set { reviewed = value; }
        }
    }
    
    
    [Developer("Kang", "20", Reviewed = true)]
    class Program
    {
        static void Main(string[] args)
        {
            // Program class의 타입을 받음
            GetAttribute(typeof(Program));
        }

        public static void GetAttribute(Type t)
        {
            // GetCustomAttribute(MemberInfo element, Type attributeType)
            // 요약:
            //     형식의 멤버에 적용 된 사용자 지정 특성을 검색 합니다. 매개 변수를 검색할 사용자 지정 특성의 유형 및 멤버를 지정 합니다.
            //
            // 매개 변수:
            //   element:
            //     파생 된 개체는 System.Reflection.MemberInfo 클래스의 생성자, 이벤트, 필드, 메서드 또는 속성 멤버를 설명 하는
            //     클래스입니다.
            //
            //   attributeType:
            //     형식 또는 검색할 사용자 지정 특성의 기본 형식입니다.
            //
            // 반환 값:
            //     형식의 단일 사용자 지정 특성에 대 한 참조를 attributeType 에 적용 되는 element, 또는 null 이러한 특성이 없는 경우.
            DeveloperAttribute developerAttribute = 
            	(DeveloperAttribute)Attribute.GetCustomAttribute(t, typeof(DeveloperAttribute));

            if(developerAttribute == null)
            {
                Console.WriteLine("해당 Attribute를 찾을 수 없습니다.");
                return;
            }

            Console.WriteLine("name of developerAttribute : " + developerAttribute.Name);
            Console.WriteLine("Level of developerAttribute : " + developerAttribute.Level);
            Console.WriteLine("Reviewed of developerAttribute : " + developerAttribute.Reviewed);
        }
    }

Reflection과 Attributes

// C#

    class Important : Attribute
    {
        string message;

        public Important(string message)
        {
            this.message = message;
        }
    }
    class Monster
    {
        [Important("very important")]
        public int hp;
        protected int attck;
        private float speed;
    }

    class Program
    {
        static void Main(string[] args)
        {
            Monster monster = new Monster();
            Type type = monster.GetType();

            // public으로 되어있는 hp만 받아옴
            FieldInfo[] fields = type.GetFields();

            var attribute = fields[0].GetCustomAttributes();
        }
    }
profile
복습하기 위해 쓰는 글

0개의 댓글