반응형
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();
}
}
}
- 실행 결과