Reflection 기본 설명 및 구조
종종 메서드의 이름이나 구조가 변경될 수 있는 환경에서 동적으로 메서드를 호출해야 때가 있습니다.
Reflection 은 프로그램이 실행 중에 자신의 구조를 검사하고 조작할 수 있는 기능을 제공하는데 예를 들어 특정 유형의 멤버를 찾거나 인스턴스를 동적으로 생성하는 데 사용될 수 있습니다.
Reflection 기능을 사용할 필요가 없는 경우는 다음과 같이 일반 객체를 생성해서 사용합니다.
BS2Event instance = new BS2Event();
object value = instance.FieldName;
리플렉션을 사용하는 경우는 다음과 같이 사용합니다.
Type structureType = typeof(BS2Event);
FieldInfo field = structureType.GetField("FieldName");
BS2Event instance = new BS2Event
{
FieldName = "고양이"
};
object nameValue = field.GetValue(instance);
그렇다면 왜 굳이 이렇게 복잡한 과정을 거쳐서 Reflection 기능을 사용할까요
Reflection 의 장단점 및 사용하는 상황
Reflection은 실행 중에 코드를 조사하고 조작하는 기술입니다. 이를 통해 코드를 작성할 때 정확한 타입을 알지 못하거나 동적으로 다룰 필요가 있는 경우 사용됩니다. 또한 메서드의 이름이나 파라미터가 변경되더라도 코드를 수정하지 않고 사용할 수 있습니다. 하드 코딩을 피하고 동적으로 가져와서 사용할 수 있는 거죠.
다음은 예시 코드입니다.
// 메서드 이름을 동적으로 가져와서 호출
MethodInfo method = type.GetMethod("SomeMethod");
if (method != null)
{
method.Invoke(instance, null);
}
만약 위 코드에서 method의 이름이 바뀐다 해도 아래와 같이 단순히 메서드의 이름만 변경해서 적용시킬 수 있습니다.
// 메서드 이름을 동적으로 가져와서 호출
MethodInfo method = type.GetMethod("NewMethodName");
if (method != null)
{
method.Invoke(instance, null);
}
위와 같이 Reflection을 사용하는 건 코드를 유연하게 만들어 주지만, 다음과 같이 단점들도 존재합니다.
- 성능 저하 : Reflection은 실행 중에 타입 정보를 조사하기 때문에 성능에 영향을 미칠 수 있습니다. 특히, 많은 양의 Reflection을 사용하면 성능이 크게 저하될 수 있습니다.
- 컴파일 타임 검사 불가능 : Reflection을 사용하면 컴파일 타임에 코드를 검사할 수 없어서 잘못된 참조나 타입 사용으로 인한 오류를 런타임에만 확인할 수 있습니다.
- 가독성 감소 : Reflection 코드는 일반적으로 가독성이 떨어지며 디버깅이 어려울 수 있습니다. 코드를 이해하기 어려워지고 유지보수가 어려워질 수 있습니다.
따라서 Reflection을 사용하기 전에 필요한지 검토하고, 다른 대안이 없는 경우에만 사용하는 것이 좋습니다.
Reflection 없이도 충분히 타입 세이프하게 작성할 수 있다면, Reflection을 사용하지 않는 것이 바람직할 수 있습니다.
Reflection을 사용하는 상황
Reflection은 주로 다음과 같은 상황에서 사용될 수 있습니다.
- 동적 코드 생성 : Reflection을 사용하면 런타임에 타입을 알고 있는 경우에도 타입 정보를 사용하여 새로운 객체를 생성하거나 메서드를 호출할 수 있습니다. 특히, 코드를 컴파일할 때 알 수 없는 경우에 동적으로 코드를 생성할 때 활용할 수 있습니다.
- 다형성을 고려한 코드 작성 : 제네릭이나 다형성을 고려해야 할 때, Reflection을 사용하여 타입 정보를 동적으로 처리할 수 있습니다. 일반적으로 컴파일 타임에 알 수 없는 제네릭 타입을 처리하는 경우나 다형성을 활용하는 경우 Reflection이 도움이 될 수 있습니다.
- 외부 라이브러리나 API의 동적 호출 : 외부 라이브러리나 API를 사용할 때, Reflection을 통해 해당 라이브러리의 메서드나 속성 등을 동적으로 호출하는 경우가 있습니다. 이는 라이브러리의 버전이나 기능 변경에 대응하기 위한 유연성을 제공합니다.
- Attribute와 관련된 작업 : Reflection은 Attribute를 사용하여 코드에 메타데이터를 추가하고 이를 런타임에 동적으로 읽을 때 사용됩니다. 예를 들어, 특정 Attribute가 부여된 클래스를 찾아내거나, 속성의 Attribute를 확인하는 데 활용될 수 있습니다.
- 테스트 프레임워크나 DI(Dependency Injection) 컨테이너 : Reflection을 사용하여 테스트 케이스를 자동으로 찾거나, DI 컨테이너에서 객체를 생성 및 주입할 때 사용할 수 있습니다.
위와 같이 Reflection은 정적인 코드로는 처리하기 어려운 동적인 요구사항이나 런타임에 알 수 없는 정보를 다룰 때 유용합니다.
저 같은 경우 특히 3번인 외부 라이브러리나 API 동적 호출 상황에서 사용하였는데
라이브러리의 버전이나 기능이 변경될 경우 정적으로 코드를 작성하면 새로운 버전이나 변경된 기능에 대응하기 어렵기 때문에 Reflection을 사용하였습니다.
'C#' 카테고리의 다른 글
GitHub Copilot Chat 사용 방법(Visual Studio) (0) | 2024.01.18 |
---|---|
.NET에서 IntPtr 및 네이티브 코드와의 상호 작용 (0) | 2024.01.11 |
Binary(이진 파일)의 장점 및 사용 (1) | 2023.12.19 |
ASP.NET Core 서비스 라이프타임 종류 및 특징 (0) | 2023.12.14 |
Interop 라이브러리 (0) | 2023.12.12 |