<개인공부>/[C#]

[C#] 타입 조사 Type, 리플렉션(reflection)

BlockDMask 2022. 9. 11. 20:00
반응형

안녕하세요. BlockDMask 입니다.
오늘은 C#에서 객체의 타입 정보, 클래스의 타입정보를 얻을 수 있는 방법에 대해서 알아보려합니다.

<목차>
1. C# 타입조사 (feat. Type 클래스)
2. C# 필드, 메서드, 생성자 조사 (feat. 리플렉션 네임스페이스)

 

1. 씨샵 타입 조사 (Type 클래스)

씨샵에서는 타입을 나타내기 위한 Type 이라는 클래스가 존재합니다.
Type을 이용해서 우리는 객체의 타입, 클래스의 타입등을 받아서 구분할 수 있습니다.

런타임 상태 (프로그램이 시작되서 동작하고 있는 상태, 프로세스 상태)일때
클래스나 클래스의 객체의 타입 정보를 조사하고 싶을 때 아래와 같은 방법을 사용합니다.

1. typeof(클래스)
2. 객체.GetType() 

이렇게 두가지 방법을 통해서 우리는 Type 객체를 얻을 수 있습니다. 
이 Type 객체를 통해서 타입을 구분하거나 할 수 있게 됩니다.

예제를 한번 볼까요?

using System;
using System.Runtime.Intrinsics.X86;

class Worker
{
    public Worker() {
        // 생성자
    }

    public void DoWork()
    {
        // 메서드
    }
}

class Program
{
    public static void Main()
    {
        // 이미 정해져 있는 클래스
        Console.WriteLine("\n\nint 클래스(타입)");

        // (1) 클래스의 타입을 얻어온다.
        Type a1 = typeof(int);
        Console.WriteLine($"typeof(int) : {a1}");

        // (2) 객체의 타입을 가지고 온다.
        int num = 20;
        Type a2 = num.GetType();
        Console.WriteLine($"num.GetType() : {a2}");

        ////////////////////////////////////////////////////////////
        // 사용자 정의 클래스
        Console.WriteLine("\n\n사용자 정의 클래스");

        // (1) 클래스의 타입을 얻어온다.
        Type b1 = typeof(Worker);
        Console.WriteLine($"typeof(Worker) : {b1}");

        // (2) 객체의 타입을 가지고 온다.
        Worker work = new Worker();
        Type b2 = work.GetType();
        Console.WriteLine($"work.GetType() : {b2}");
    }
}

C# Type

결과를 보시면 Type들이 바로바로 나오는걸 알수있습니다.
Type 클래스 내부에는 "클래스인가? IsClass(), 배열인가? IsArray()" 등을 조사할수있는 많은 메서드들도 존재합니다.
한번 내부를 살펴보는 것도 많은 도움이 될 것 같아요.

Type 클래스에 대해서 궁금하시다면 
공식문서 : https://docs.microsoft.com/ko-kr/dotnet/api/system.type?view=net-6.0

 

 

2. 씨샵 생성자, 필드, 메소드 조사 (Reflection Namespace)

클래스의 내부에 어떤 필드가 들어있고 어떤 메서드들이 있고 생성자는 어떤게 있는지 조사가 필요하다면
reflection 네임스페이스를 사용하면 됩니다.

reflection 네임스페이스 내부에는 타입 관련한 많은 클래스들이 존재하는데 
여기서 우리는 딱 세가지만 배우겠습니다.

1. MethodInfo : 메서드를 받는 클래스 (멤버함수)
2. FieldInfo : 필드를 받는 클래스 (멤버변수)
3. ConstructorInfo : 클래스 생성자를 받는 클래스

using System;
using System.Reflection;    // 필요!

class Worker
{
    // 필드
    public int num1 = 0;
    public string str = "";

    public Worker() 
    {
        // 생성자1
    }
    public Worker(int num)
    {
        // 생성자2
    }
    public Worker(string str)
    {
        // 생성자2
    }

    public void DoWork1()
    {
        // 메서드
    }
    public void DoWork2()
    {
        // 메서드
    }
    public void DoWork3()
    {
        // 메서드
    }
}

class Program
{
    public static void Main()
    {
        // 객체 생성
        Worker work = new Worker();

        // (1) 객체의 메소드들을 얻어온다.
        Console.WriteLine("1. work.GetType().GetMethods()");
        MethodInfo[] methods = work.GetType().GetMethods();
        // Type t = work.GetType().
        // t.GetMethods() 와 동일.

        foreach (var method in methods)
        {
            Console.WriteLine(method);
        }

        // (2) 객체의 필드를 얻어옵니다.
        Console.WriteLine("\n2. work.GetType().GetFields()");
        FieldInfo[] fields = work.GetType().GetFields();
        
        foreach(var field in fields)
        {
            Console.WriteLine(field);
        }

        // (3) 객체의 생성자를 얻어옵니다.
        Console.WriteLine("\n3. work.GetType().GetConstructors()");
        ConstructorInfo[] constructors = work.GetType().GetConstructors();

        foreach (var cons in constructors)
        {
            Console.WriteLine(cons);
        }
    }
}

C# GetFields, GetMethods, GetConstructors

이렇게 객체 내부에 생성자가 몇개인지, 필드가 몇개인지, 메소드가 몇개있는지 그리고 그 형태들은 어떠한지 상세하게 알 수 있습니다.

당연히 아시겠지만
work.GetMethod()는 Type객체로 받은 다음에 GetFields() 등으로 메소드를 호출 해도 됩니다.
Type t = workd.GetMethod();
var a = t.GetFields();
var b = t.GetMethods(); 
var c = t.GetConstructors();

리플렉션 네임스페이스 문서 : https://docs.microsoft.com/ko-kr/dotnet/api/system.reflection?view=net-6.0 

이상으로 오늘은 C#에서 타입을 조사하는 방법에 대해서 알아보았습니다.
감사합니다.

반응형