Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

C#에서 현재 Type의 멤버를 가져오는 방법 완벽 정리

C#에서 리플렉션(Reflection)을 활용하면 특정 타입(Type)이 가지고 있는 필드, 메서드, 생성자 등 모든 멤버 정보를 런타임에 동적으로 조회할 수 있습니다. 이번 글에서는 Type.GetMembers() 메서드와 Type.GetField() 메서드를 사용하여 현재 타입의 멤버를 가져오는 방법을 예제와 함께 자세히 알아보겠습니다.

핵심 개념: GetMembers()와 GetField()

  • GetMembers(): 해당 타입의 모든 멤버(메서드, 필드, 생성자 등)를 MemberInfo[] 배열로 반환합니다.
  • GetField(string name): 지정한 이름과 일치하는 public 필드를 FieldInfo 객체로 반환합니다. 이름이 null이면 ArgumentNullException이 발생합니다.

예제 1: 기본적인 멤버 조회

다음은 Subject 클래스의 모든 멤버와 특정 필드 정보를 가져오는 기본 예제입니다.

using System;
using System.Reflection;
public class Demo {
    public static void Main() {
        Type type = typeof(Subject);
        try {
            FieldInfo fieldInfo = type.GetField("SubName");
            MemberInfo[] info = type.GetMembers();
            Console.Write("Members = ");
            for (int i = 0; i < info.Length; i++)
                Console.WriteLine(" {0}", info[i]);
            Console.WriteLine("FieldInfo = {0}", fieldInfo);
        }
        catch (ArgumentNullException e) {
            Console.Write("{0}", e.GetType(), e.Message);
        }
    }
}
public class Subject {
    public string SubName = "Science";
}

실행 결과

위 코드를 실행하면 다음과 같이 Subject 클래스가 상속받은 Object 클래스의 멤버까지 포함한 전체 멤버 목록이 출력됩니다.

Members =  System.String ToString()
 Boolean Equals(System.Object)
 Int32 GetHashCode()
 System.Type GetType()
 Void .ctor()
 System.String SubName
FieldInfo = System.String SubName

출력 결과를 보면 ToString(), Equals(), GetHashCode(), GetType() 같은 Object 클래스에서 상속된 메서드들과 기본 생성자 .ctor(), 그리고 직접 선언한 필드 SubName이 함께 표시되는 것을 확인할 수 있습니다.

예제 2: BindingFlags로 조회 범위 지정하기

GetMembers() 메서드에 BindingFlags 열거형을 전달하면 조회할 멤버의 범위를 세밀하게 제어할 수 있습니다. 아래 예제는 public 인스턴스 멤버만 조회하는 코드입니다.

using System;
using System.Reflection;
public class Demo {
    public static void Main() {
        Type type = typeof(Subject);
        try {
            FieldInfo fieldInfo = type.GetField("SubName");
            MemberInfo[] info = type.GetMembers(BindingFlags.Public | BindingFlags.Instance);
            Console.Write("Members = ");
            for (int i = 0; i < info.Length; i++)
                Console.WriteLine(" {0}", info[i]);
            Console.WriteLine("FieldInfo = {0}", fieldInfo);
        }
        catch (ArgumentNullException e) {
            Console.Write("{0}", e.GetType(), e.Message);
        }
    }
}
public class Subject {
    public string SubName = "Science";
}

실행 결과

Members =  System.String ToString()
 Boolean Equals(System.Object)
 Int32 GetHashCode()
 System.Type GetType()
 Void .ctor()
 System.String SubName 
FieldInfo = System.String SubName

BindingFlags 주요 옵션 정리

  • BindingFlags.Public: public으로 선언된 멤버만 검색합니다.
  • BindingFlags.NonPublic: private, internal, protected 멤버를 포함하여 검색합니다.
  • BindingFlags.Instance: 인스턴스 멤버(정적이 아닌 멤버)를 검색합니다.
  • BindingFlags.Static: 정적(static) 멤버를 검색합니다.

여러 플래그는 비트 OR 연산자(|)로 조합하여 사용할 수 있으며, 이를 통해 원하는 멤버만 정확하게 필터링할 수 있습니다.

마무리

C#의 리플렉션 API인 GetMembers()GetField()를 사용하면 타입의 구조를 런타임에 동적으로 분석할 수 있습니다. 플러그인 시스템, 직렬화 라이브러리, DI 컨테이너처럼 타입 정보를 실행 중에 확인해야 하는 시나리오에서 매우 유용하게 활용됩니다. 다만 리플렉션은 일반적인 직접 호출보다 성능 오버헤드가 크므로, 필요한 경우에 한해서 신중하게 사용하는 것이 좋습니다.