프로그래밍/C#

C# 리플렉션: 동적 프로그래밍의 강력한 도구

shimdh 2025. 9. 5. 10:55
728x90

C#의 리플렉션은 런타임 시 객체의 타입을 검사하고 상호작용할 수 있는 강력한 기능을 제공합니다. 이 블로그 포스트에서는 리플렉션의 주요 개념과 실용적인 예제를 통해 그 활용 방법을 알아보겠습니다.

리플렉션의 주요 개념

어셈블리

어셈블리는 .NET 애플리케이션에서 사용되는 컴파일된 코드 라이브러리입니다. System.Reflection 네임스페이스는 Assembly 클래스를 통해 어셈블리를 로드하고 탐색할 수 있게 합니다.

타입

리플렉션의 핵심 클래스인 Type을 사용하면 클래스, 인터페이스, 열거형, 구조체 등의 메타데이터를 얻을 수 있습니다. 이를 통해 메서드, 속성, 이벤트, 필드 등의 정보를 포함한 다양한 타입 정보를 검색할 수 있습니다.

멤버

멤버에는 메서드, 속성, 생성자, 필드, 이벤트가 포함됩니다. 리플렉션을 통해 이러한 멤버를 동적으로 발견하고 조작할 수 있습니다.

속성

속성은 클래스나 메서드에 메타데이터를 추가하는 방법을 제공합니다. 리플렉션을 사용하여 이러한 속성을 검색하고 다양한 목적으로 활용할 수 있습니다.

동적 생성

리플렉션은 Activator.CreateInstance() 메서드와 Type 클래스를 사용하여 객체를 동적으로 인스턴스화할 수 있게 합니다.

728x90

실용적인 예제

1. 어셈블리 로드하기

외부 어셈블리를 동적으로 로드하는 방법을 살펴보겠습니다.

using System;
using System.Reflection;

class Program
{
    static void Main()
    {
        Assembly myAssembly = Assembly.LoadFrom("MyLibrary.dll");

        foreach (Type type in myAssembly.GetTypes())
        {
            Console.WriteLine($"발견된 타입: {type.Name}");
        }
    }
}

이 예제에서는 "MyLibrary.dll"이라는 외부 DLL을 로드하고, 어셈블리에 정의된 모든 타입을 출력합니다.

2. 타입 검사하기

어셈블리를 로드했거나 알려진 타입 참조가 있을 때 타입을 검사하는 방법입니다.

public class SampleClass
{
    public int MyProperty { get; set; }

    public void MyMethod() 
    {
       Console.WriteLine("MyMethod에서 인사합니다!");
    }
}

class Program
{
    static void Main()
    {
        Type sampleType = typeof(SampleClass);

        var propertyInfo = sampleType.GetProperty("MyProperty");
        var methodInfo = sampleType.GetMethod("MyMethod");

        Console.WriteLine($"속성 이름: {propertyInfo.Name}, 속성 타입: {propertyInfo.PropertyType}");

        SampleClass instance = new SampleClass();
        methodInfo.Invoke(instance, null);  
    }
}

이 예제에서는 SampleClass의 속성과 메서드를 리플렉션을 통해 검색하고, 동적으로 메서드를 호출합니다.

3. 속성과 작업하기

속성을 사용하여 메타데이터를 추가하고 검색하는 방법입니다.

[AttributeUsage(AttributeTargets.Class)]
public class DocumentationAttribute : Attribute 
{
   public string Author { get; }
   public string Version { get; }

   public DocumentationAttribute(string author, string version)
   {
      Author = author;
      Version = version;
   }
}

[Documentation("John Doe", "1.0")]
public class MyAnnotatedClass {}

class Program 
{
   static void Main()
   {
       Type annotatedType = typeof(MyAnnotatedClass);

       object[] attributes = annotatedType.GetCustomAttributes(typeof(DocumentationAttribute), false);

       if(attributes.Length > 0) 
       {
           var docAttr = (DocumentationAttribute)attributes[0];
           Console.WriteLine($"작성자: {docAttr.Author}, 버전: {docAttr.Version}");
       } 
   }
}

이 예제에서는 사용자 정의 속성을 생성하고, 이를 클래스에 적용한 후 리플렉션을 통해 속성 정보를 검색합니다.

결론

System.Reflection 네임스페이스는 C#에서 동적 프로그래밍 패턴을 구현하는 데 필수적인 도구입니다. 확장 가능한 애플리케이션을 구축하거나 런타임에 알 수 없는 타입과 작업해야 하는 경우 매우 유용합니다. 그러나 메타데이터를 검사하는 데 추가적인 오버헤드가 발생할 수 있으므로 성능에 대한 고려가 필요합니다.

728x90