본문 바로가기
Study/C#

[C#] 리플렉션(Reflection)

by 스테디코디스트 2023. 11. 1.
반응형

1. 리플렉션(reflection)이란?

- 애플리케이션 실행 중 어셈블리의 내용(메서드, 프로퍼티, 생성자 등, 인스턴스의 데이터 타입 정보)을 확인하거나 검사하려는 경우 사용되는 기능

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

- 컴파일 시에 알 수 없었던 타입이나 멤버들을 찾아내고 사용할 수 있게 해주는 메커니즘

 

2. 리플렉션의 목적

- 애플리케이션 개발시, 디버깅 또는 런타임에 알 수 없는 객체의 동작을 분석하기 위함.

- 외부 라이브러리에 존재하는 클래스 및 메서드를 분석하기 위함.

- 개발 도구 자체를 개발하거나 분석도구를 만들때 사용

- 유니티의 경우 에디터를 만드는데 자주 쓰임

 

3. 리플렉션의 단점

- 성능 오버헤드를 일으킬 수 있음.

- 컴파일 시에 타입 안정성을 해침.

- 전반적으로 느림(문자열 검색이 수행됨)

- 보안 때문에 소스코드를 실행할 수 없는 경우 무용지물이 될 수 있음.

- 코드를 이식하지 않아도 되는 장점이 OOP의 추상화를 위반함

 

4. 타입 오브젝트

함수명 Return 타입 설명
GetType() Type 변수의 타입을 반환한다.
typeof() Type 현재 타입을 반환한다.
GetMembers() MemberInfo[] 해당 데이터 타입의 모든 멤버를 배열로 반환한다.
GetConstructors() ConstructorInfo[] 해당 데이터 타입의 모든 생성자를 배열로 반환한다.
GetMethods() MethodInfo[] 해당 데이터 타입의 모든 메서드를 배열로 반환한다.
GetFields() FieldInfo[] 해당 데이터 타입의 모든 필드를 배열로 반환한다.
Getinterfaces() Type[] 해당 데이터 타입이 상속하는 모든 인터페이스를 배열로 반환한다.
GetProperties() PropertyInfo[] 해당 데이터 타입의 모든 프로퍼티를 배열로 반환한다.

 

5. 소스코드 예제

// Reflection
using System;
using System.Reflection;

namespace StudyCSharp
{
    interface IMove { }

    interface IEat { }

    class Animal : IMove, IEat
    {
        public int age;
        public string name;

        public int id {  get; set; }

        public bool isCarnimore {  get; set; }

        public Animal(string name, int age)
        {
            this.age = age;
            this.name = name;
        }

        public void eat()
        {
            Console.WriteLine("먹는다!");
        }

        private void sleep() // private 타입은 표시되지 않음
        {
            Console.WriteLine("잔다!");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Animal animal = new Animal("고양이", 4);


            // GetType()
            Type type = animal.GetType();
            Console.WriteLine("타입(Type) : ");
            Console.WriteLine("\t{0}", type);
            Console.WriteLine();


            // typeof()
            Type type2 = typeof(Animal); // typeof 내부에는 Type 형식만 올 수 있음(animal과 같은 변수는 올 수 없음)            ;
            Console.WriteLine("타입(typeof) : ");
            Console.WriteLine("\t" + type2);
            Console.WriteLine();
             

            // 멤버 = 생성자 + 메소드 + 필드
            MemberInfo[] meminfo = type.GetMembers();
            Console.WriteLine("멤버(Member) : ");

            foreach (MemberInfo mem in meminfo)
            {
                Console.WriteLine("\t{0}", mem);
            }
            Console.WriteLine();


            // 생성자
            ConstructorInfo[] coninfo = type.GetConstructors();
            Console.WriteLine("생성자(Constructor) : ");

            foreach (ConstructorInfo con in coninfo)
            {
                Console.WriteLine("\t{0}", con);
            }
            Console.WriteLine();           


            // 메소드
            MethodInfo[] methodinfo = type.GetMethods();
            Console.WriteLine("메소드(Method) : ");

            foreach (MethodInfo method in methodinfo)
            {
                Console.WriteLine("\t{0}", method);
            }
            Console.WriteLine();


            // 필드
            FieldInfo[] fieldinfo = type.GetFields();
            Console.WriteLine("필드(Field) : ");

            foreach (FieldInfo field in fieldinfo)
            {
                Console.WriteLine("\t{0}", field);
            }
            Console.WriteLine();

            
            // 인터페이스
            Type[] interfaces = type.GetInterfaces();
            Console.WriteLine("인터페이스(Interface) : ");

            foreach (Type inter in interfaces)
            {
                Console.WriteLine("\t{0}", inter);
            }
            Console.WriteLine();


            // 프로퍼티
            PropertyInfo[] propertyInfo = type.GetProperties();
            Console.WriteLine("프로퍼티(Property) : ");

            foreach (PropertyInfo prop in propertyInfo)
            {
                Console.WriteLine("\t{0}", prop);
            }
            Console.WriteLine();
        }        
    }        
}

- 실행 결과