C#/리플렉션(Reflection)

[C#]리플렉션(Reflection) - 클래스 생성자 정보 접근

DevStory 2022. 9. 27.

클래스 생성자 정보 접근

이번 포스팅은 C#의 Reflection API를 사용하여 클래스 생성자 정보를 확인할 수 있는 방법을 소개합니다.


생성자 정보 가져오는 방법

Reflection API를 사용하여 클래스 생성자 정보를 확인할 수 있는 방법은 두 가지입니다.

 

첫 번째 방법은 Type 클래스에서 제공하는 GetConstructors() 메서드를 사용하여 생성자 정보를 배열로 가져올 수 있습니다.

public ConstructorInfo[] GetConstructors();
public abstract ConstructorInfo[] GetConstructors(BindingFlags bindingAttr);

GetConstructors() 메서드는 오버로드된 두 가지 버전이 존재합니다. 매개변수가 없는 첫 번째 GetConstructors() 메서드는 해당 타입의 접근 한정자가 public인 생성자 정보를 반환하며, 두 번째 GetConstructors() 메서드는 열거형인 BindingFlags를 매개변수로 가지며, 특정 조건에 해당하는 생성자 정보를 반환합니다.

 

생성자 정보를 확인할 수 있는 또 다른 방법으로 Type 클래스에서 제공하는 GetConstructor() 메서드를 사용할 수 있습니다.

public ConstructorInfo? GetConstructor(Type[] types);
public ConstructorInfo? GetConstructor(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers);
public ConstructorInfo? GetConstructor(BindingFlags bindingAttr, Binder? binder, Type[] types, ParameterModifier[]? modifiers);

GetConstructor() 메서드는 오버로드된 세 가지 버전이 존재하며, 특정 조건에 해당하는 하나의 생성자 정보만 반환합니다.


GetConstructors 메서드

다음 예제는 GetConstructors() 메서드를 사용하여 Program 클래스의 접근 한정자가 public인 생성자의 정보(접근 한정자, Static 여부, 생성자 여부)를 콘솔에 출력합니다.

class Program
{
  public Program()
  {

  }

  public Program(string str)
  {

  }

  private Program(int num)
  {

  }

  static Program()
  {

  }

  static void Main(string[] args)
  {
    Type type = typeof(Program);

    foreach (ConstructorInfo constructor in type.GetConstructors())
    {
      Console.WriteLine("Name: {0}, IsPublic: {1}, IsPrivate: {2}, IsStatic: {3}, IsConstructor: {4}",
          constructor.Name, constructor.IsPublic, constructor.IsPrivate, constructor.IsStatic, constructor.IsConstructor);
    }
  }
}

[실행 결과]

Name: .ctor, IsPublic: True, IsPrivate: False, IsStatic: False, IsConstructor: True
Name: .ctor, IsPublic: True, IsPrivate: False, IsStatic: False, IsConstructor: True

 

다음 예제는 열거형인 BindingFlags를 매개변수로 가지는 GetConstructors() 메서드를 호출하여 접근 한정자가 private이거나 정적(static) 생성자인 생성자의 정보(접근 한정자, Static 여부, 생성자 여부)를 콘솔에 출력합니다.

class Program
{
  public Program()
  {

  }

  public Program(string str)
  {

  }

  private Program(int num)
  {

  }

  static Program()
  {

  }

  static void Main(string[] args)
  {
    Type type = typeof(Program);
    foreach (ConstructorInfo constructor in type.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic))
    {
      Console.WriteLine("Name: {0}, IsPublic: {1}, IsPrivate: {2}, IsStatic: {3}, IsConstructor: {4}",
          constructor.Name, constructor.IsPublic, constructor.IsPrivate, constructor.IsStatic, constructor.IsConstructor);
    }

    foreach (ConstructorInfo constructor in type.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic))
    {
      Console.WriteLine("Name: {0}, IsPublic: {1}, IsPrivate: {2}, IsStatic: {3}, IsConstructor: {4}",
          constructor.Name, constructor.IsPublic, constructor.IsPrivate, constructor.IsStatic, constructor.IsConstructor);
    }
  }
}

[실행 결과]

Name: .ctor, IsPublic: False, IsPrivate: True, IsStatic: False, IsConstructor: True
Name: .cctor, IsPublic: False, IsPrivate: True, IsStatic: True, IsConstructor: False

접근 한정자가 private인 생성자의 정보를 가져오기 위해서는 GetConstructors() 메서드의 매개변수로 아래 코드를 전달합니다.

- BindingFlags.Instance | BindingFlags.NonPublic

 

정적(static)인 생성자의 정보를 가져오기 위해서는 GetConstructors() 메서드의 매개변수로 아래 코드를 전달합니다.

- BindingFlags.Static | BindingFlags.NonPublic


GetConstructor 메서드

GetConstructor() 메서드는 특정 조건에 해당하는 단일 생성자 정보를 반환합니다.

class Program
{
  public Program()
  {

  }

  public Program(string str)
  {

  }

  private Program(int num)
  {

  }

  static Program()
  {

  }

  static void Main(string[] args)
  {
    Type type = typeof(Program);

    ConstructorInfo publicDefaultConstructor = type.GetConstructor(Type.EmptyTypes);

    ConstructorInfo privateConstructor = type.GetConstructor(
        BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(int) }, null);

    ConstructorInfo publicConstructor = type.GetConstructor(
        BindingFlags.Instance | BindingFlags.Public, null, new[] { typeof(string) }, null);

    ConstructorInfo staticConstructor = type.GetConstructor(
        BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { }, null);
  }
}

매개변수가 없으며, 접근 한정자가 public인 생성자 정보를 가져오기 위해서는 GetConstructor() 메서드의 매개변수로 아래 코드를 전달합니다.

- Type.EmptyTypes

 

접근 한정자가 private이며, int 타입인 매개변수를 가지는 생성자 정보를 가져오기 위해서는 GetConstructor() 메서드의 매개변수로 아래 코드를 전달합니다.

- 플래그: BindingFlags.Instance | BindingFlags.NonPublic

- 매개변수 타입 배열: new[] { typeof(int) }

 

접근 한정자가 public이며, string 타입인 매개변수를 가지는 생성자 정보를 가져오기 위해서는 GetConstructor() 메서드의 매개변수로 아래 코드를 전달합니다.

- 플래그: BindingFlags.Instance | BindingFlags.Public

- 매개변수 타입 배열: new[] { typeof(string) }

 

접근 한정자가 private이며, 매개변수가 없는 정적(static)인 생성자 정보를 가져오기 위해서는 GetConstructor() 메서드의 매개변수로 아래 코드를 전달합니다.

- 플래그: BindingFlags.Static | BindingFlags.NonPublic

- 매개변수 타입 배열: new Type[] {}


생성자의 매개변수 정보

ConstructorInfo 인스턴스에서 GetParameters() 메서드를 호출하여 매개변수 정보를 배열로 가져올 수 있습니다.

 

다음 예제는 GetParameters() 메서드를 호출하여 매개변수 정보를 콘솔에 출력하며, ParameterInfo 클래스에서 제공하는 프로퍼티는 주석으로 설명하였습니다.

class Program
{
  public Program(int num, out string strValue, bool b = false)
  {
    strValue = "Hello";
  }

  static void Main(string[] args)
  {
    Type type = typeof(Program);
    var outStringType = Type.GetType("System.String&");

    ConstructorInfo constructor = type.GetConstructor(
        BindingFlags.Instance | BindingFlags.Public, 
        null, new Type[] { typeof(int), Type.GetType("System.String&"), typeof(bool) }, null);

    foreach (ParameterInfo param in constructor.GetParameters())
    {
      // Name: 매개변수의 이름
      // ParameterType: 매개변수의 타입 정보
      // Position: 매개변수의 위치
      // IsOut: out 매개변수 여부
      // IsOptional: Optional 매개변수 여부
      Console.Write("매개변수 이름: {0}, 타입: {1}, 위치: {2}, out 여부: {3}, Optional 여부: {4}, ",
          param.Name, param.ParameterType.Name, param.Position, param.IsOut, param.IsOptional);

      // HasDefaultValue: 기본값 값이 존재 여부
      // DefaultValue: 매개변수의 기본값
      if (param.HasDefaultValue)
      {
        Console.Write("Default Value: " + param.DefaultValue);
      }
      Console.WriteLine();
    }
  }
}

[실행 결과]

매개변수 이름: num, 타입: Int32, 위치: 0, out 여부: False, Optional 여부: False,
매개변수 이름: strValue, 타입: String&, 위치: 1, out 여부: True, Optional 여부: False,
매개변수 이름: b, 타입: Boolean, 위치: 2, out 여부: False, Optional 여부: True, Default Value: False
반응형

'C# > 리플렉션(Reflection)' 카테고리의 다른 글

[C#]리플렉션(Reflection)이란?  (0) 2022.09.25

댓글