전체코드

using System.ComponentModel;
using System.Numerics;
using System.Threading;
using System.Collections.Generic;
using CSharp;
using System.Reflection;

namespace CSharp
{
    class Program
    {
        // Reflection
        // 개념적으로 중요함
        // x-ray 찍는것으로 비유 가능

        /// <summary>
        /// 몬스터 클래스를 만듬
        /// </summary>
        /// <param name="args"></param>
        /// 
        // Attribute 런타임중에 힌트를 남길 수 있음
        // 컴퓨터가 런타임중에 확인할 수 있는 주석

        class Important : System.Attribute 
        {
            String message;

            public Important(string message)
            {
                this.message = message;
            }
        }

        class Monster
        {
            [Important("very important")]
            public int hp;
            protected int attack;
            private float speed;

            void Attack() { }
        }

        static void Main(string[] args)
        {
            Monster monster = new Monster();

            // 클래스의 모든 정보를 가져올 수 있다.
            Type type = monster.GetType();

            var fields = type.GetFields(System.Reflection.BindingFlags.Public
                | System.Reflection.BindingFlags.NonPublic
                | System.Reflection.BindingFlags.Static
                | System.Reflection.BindingFlags.Instance);

            foreach(FieldInfo field in fields)
            {
                string access = "protected";
                if (field.IsPublic) access = "public";
                else if (field.IsPrivate) access = "private";

                var Attribute = field.GetCustomAttributes();

                Console.WriteLine($"{access}{field.FieldType.Name}{field.Name}");

            }

        }
    }
}

📖 Reflection(리플렉션)이란?

"C# 객체의 내부 정보를 X-Ray 찍듯이 런타임 중에 들여다보고, 분석하고, 심지어 조작까지 가능하게 해주는 기능"


💥 Reflection이 왜 필요할까?

1️⃣ 타입 정보 탐색

  • 어떤 객체인지 이름, 필드, 메서드, 이벤트 등 모든 정보를 런타임에 확인 가능
  • 컴파일 시점이 아닌, 실행 중에 동적 확인 및 처리

2️⃣ 동적 호출

  • 메서드 이름만 문자열로 받아서, 그 메서드를 실행하고 싶을 때 사용
  • (예: 테스트 자동화 프레임워크가 테스트 메서드들 동적 호출)

3️⃣ 유니티 개발에서도 중요

  • Inspector 창에서 private 멤버도 보이게 하는 [SerializedField] 같은 기능도 Reflection 기반
  • 런타임 중에 오브젝트 정보를 파악하는 디버깅 도구 제작에도 활용

📐 기본 예제 분석 - Monster 클래스와 Reflection 활용

using System;
using System.Reflection;

namespace CSharp
{
    class Program
    {
        class Monster
        {
            public int hp;
            protected int attack;
            private float speed;

            void Attack() { }
        }

        static void Main(string[] args)
        {
            Monster monster = new Monster();

            Type type = monster.GetType();

            FieldInfo[] fields = type.GetFields(
                BindingFlags.Public |
                BindingFlags.NonPublic |
                BindingFlags.Instance |
                BindingFlags.Static);

            foreach (FieldInfo field in fields)
            {
                string access = "protected";

                if (field.IsPublic)
                    access = "public";
                else if (field.IsPrivate)
                    access = "private";

                Console.WriteLine($"{access} {field.FieldType.Name} {field.Name}");
            }
        }
    }
}

🔎 한 줄 한 줄 분석

코드설명
Type type = monster.GetType()몬스터 객체의 타입 정보를 Type으로 가져옴
GetFields(...)필드 정보들 가져옴 (접근 지정자, 타입 등 포함)
BindingFlags어떤 필드들을 가져올지 조건 지정
field.IsPublicpublic 여부 체크
field.FieldType.Name필드 자료형 이름
field.Name필드 이름
Console.WriteLine(...)필드 정보 출력

📌 BindingFlags 정리

플래그의미
Publicpublic 멤버만
NonPublicprivate/protected 멤버 포함
Instance인스턴스 필드만
Staticstatic 필드만

💎 출력 결과

public Int32 hp
protected Int32 attack
private Single speed

🌟 GetType()과 typeof 차이

구분설명예시
GetType()런타임에 객체 인스턴스의 타입을 알아냄monster.GetType()
typeof컴파일 타임에 타입 정보를 가져옴typeof(Monster)

📣 실전에서 Reflection은 언제 필요할까?

상황설명
플러그인 시스템외부 DLL에서 타입을 동적 로드
테스트 자동화테스트 메서드 이름으로 동적 실행
Unity Editor인스펙터에 private 멤버 표시
ORM/Serialization객체를 JSON으로 변환할 때 필드 나열

🎀 Attribute와 Reflection


🎈 Attribute란?

  • 런타임에 읽을 수 있는 메타데이터
  • 주석처럼 보이지만, 컴파일 후에도 남아서 런타임에 읽을 수 있음
  • 대표 예: SerializedField

📐 Attribute 사용 예제

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

📐 Attribute 읽는 방법

FieldInfo field = type.GetField("hp");
var attributes = field.GetCustomAttributes();

📐 전체 코드 예제 (Attribute까지 포함)

using System;
using System.Reflection;

namespace CSharp
{
    class Important : Attribute
    {
        string message;
        public Important(string message) { this.message = message; }
    }

    class Monster
    {
        [Important("very important")]
        public int hp;
        protected int attack;
        private float speed;

        void Attack() { }
    }

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

            FieldInfo[] fields = type.GetFields(
                BindingFlags.Public |
                BindingFlags.NonPublic |
                BindingFlags.Instance |
                BindingFlags.Static);

            foreach (FieldInfo field in fields)
            {
                string access = field.IsPublic ? "public" :
                                field.IsPrivate ? "private" :
                                "protected";

                var attributes = field.GetCustomAttributes();

                Console.Write($"{access} {field.FieldType.Name} {field.Name}");

                foreach (var attr in attributes)
                {
                    if (attr is Important important)
                    {
                        Console.Write($" - Attribute: {important}");
                    }
                }

                Console.WriteLine();
            }
        }
    }
}

📣 출력 예시

public Int32 hp - Attribute: Important
protected Int32 attack
private Single speed

📌 Attribute 정리

포인트설명
선언class MyAttribute : Attribute
부착[MyAttribute(...)]
읽기GetCustomAttributes()

🏁 정리 표

개념설명
Reflection런타임에 객체 정보를 읽고 조작
GetType객체 타입 정보 조회
typeof타입 직접 조회 (컴파일 타임)
GetFields필드 목록 조회
Attribute런타임용 메타데이터
Custom Attribute사용자 정의 메타데이터

🎁 실무 팁

  • Reflection은 성능이 느립니다. 남발 금지!
  • 자주 쓸 데이터는 캐싱 추천
  • Unity에서는 커스텀 인스펙터 제작 시 필수
  • JSON 직렬화/역직렬화 같은 라이브러리 내부도 Reflection 활용

profile
李家네_공부방

0개의 댓글