리플렉션(Reflection)
C#에서 런타임에 타입 정보를 읽고, 객체를 생성하거나 메서드를 호출하거나 필드 값을 가져오거나 설정할 수 있는 기능이다. 쉽게 말해, 프로그램이 자기 자신을 들여다보고 조작하는 기능이다.
리플렉션 메서드
리플렉션을 통해 사용되는 메서드들을 리플렉션 메서드라고 하며, 대표적으로 다음과 같은 것들이 있다:
- Type.GetType()
- typeof()
- type.GetMethod()
- type.GetProperty()
- Activator.CreateInstance()
- methodInfo.Invoke()
- propertyInfo.SetValue(), GetValue()
ex)
using System; using System.Reflection; namespace MyApp { public class Person { public void SayHi(string name) { Console.WriteLine($"안녕, {name}"); } } class Program { static void Main() { // 1. 타입 정보를 가져옴 Type type = typeof(Person); // 2. 타입의 인스턴스를 생성 object obj = Activator.CreateInstance(type); // 3. "SayHi" 메서드 정보를 가져옴 MethodInfo method = type.GetMethod("SayHi"); // 4. 그 메서드를 실행 (invoke) -> 안녕, 철수 method.Invoke(obj, new object[] { "철수" }); } } }장점
- 유연성
컴파일 시점에 알 수 없는 타입, 메서드, 속성 등을 런타임에 접근하거나 사용할 수 있다.
ex) 플러그인 시스템, JSON 직렬화 등에서 클래스 이름만 알아도 객체를 생성하고 활용할 수 있다.object obj = Activator.CreateInstance(Type.GetType("MyApp.Person"));
- 프레임워크/툴 구현에 유리
의존성 주입(DI), ORM, 테스트 프레임워크, 시리얼라이저 등 자동화 로직 구현에 적합하다.
ex) NUnit, Entity Framework, AutoMapper 등
- 코드 재사용성 증가
다양한 클래스나 메서드들을 공통 방식으로 다룰 수 있다.
ex) 메서드 이름이 같다면 어떤 객체든 메서드를 호출할 수 있다.
- 런타임 객체 조작 가능
private 필드 접근, 속성 값 읽기/쓰기, 메서드 호출 등을 동적으로 처리할 수 있다.
MethodInfo method = type.GetMethod("SayHi"); method.Invoke(obj, null);단점
- 성능 저하
일반적인 코드보다 느리다. 내부적으로 많은 메타데이터 검색 및 바인딩 작업이 발생한다.
- 안전성 저하
컴파일 타임에 오류를 잡지 못한다. 예를 들어 오타가 있어도 실행 시점까지 모른다.
- 보안 문제
접근 제한(private 등)을 무시하고 내부 구현에 접근할 수 있기 때문에 잘못 사용할 경우 보안 취약점이 생길 수 있다.
- 유지보수 어려움
문자열 기반으로 클래스명, 메서드명을 지정하면 리팩토링 시 IDE가 자동으로 추적해주지 못한다.
- 정적 분석 어려움
리플렉션은 코드의 흐름이 런타임에 결정되므로 정적 분석 도구 'ex) SonarQube'가 정확히 분석하기 어렵다.