프로그래밍/C#

C#의 DynamicObject: 유연한 프로그래밍을 위한 강력한 도구

shimdh 2025. 9. 8. 09:29
728x90

C#의 DynamicObject는 개발자에게 런타임에 객체의 멤버를 동적으로 정의할 수 있는 강력한 기능을 제공합니다. 이 기능은 특히 프로그램 실행 시점까지 객체의 구조를 알 수 없는 시나리오에서 유용하며, 다양한 소스에서 스키마가 변경될 수 있는 데이터를 다룰 때 유연성을 제공합니다.

DynamicObject 이해하기

DynamicObject란 무엇인가?

  • DynamicObject는 .NET에서 제공하는 기본 클래스입니다. 이를 상속하여 자신만의 동적 타입을 만들 수 있습니다.
  • DynamicObject를 상속함으로써 속성 접근, 메서드 호출 등과 같은 작업을 처리하는 메서드를 재정의할 수 있습니다.

DynamicObject를 사용하는 이유는?

  1. 유연성: 미리 정의된 구조 없이도 속성과 메서드를 즉석에서 추가할 수 있습니다.
  2. 상호 운용성: 구조가 고정되지 않은 COM 객체, 스크립팅 언어, JSON 데이터와 상호 작용할 때 유용합니다.
  3. 코드 간소화: 알 수 없는 타입이나 구조를 다룰 때 보일러플레이트 코드를 줄여줍니다.

DynamicObject의 주요 메서드

DynamicObject를 상속할 때, 동적 객체의 동작을 정의할 수 있는 여러 주요 메서드가 있습니다:

  • TryGetMember: 멤버(속성)의 값을 동적으로 가져오는 데 사용됩니다.
  • TrySetMember: 멤버(속성)의 값을 동적으로 설정하는 데 사용됩니다.
  • TryInvokeMember: 메서드를 동적으로 호출할 수 있게 해줍니다.
  • TryConvert: 타입 간의 변환을 동적으로 가능하게 합니다.
728x90

실용적인 예제

사용자 입력에 따라 API 응답의 동적 표현을 생성해야 하는 시나리오를 고려해 봅시다:

using System;
using System.Dynamic;

public class ApiResponse : DynamicObject
{
    private readonly Dictionary<string, object> _properties = new Dictionary<string, object>();

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        return _properties.TryGetValue(binder.Name, out result);
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        _properties[binder.Name] = value;
        return true;
    }
}

class Program
{
    static void Main()
    {
        dynamic response = new ApiResponse();

        // 속성을 동적으로 설정
        response.StatusCode = 200;
        response.Message = "Success";

        // 속성을 동적으로 가져오기
        Console.WriteLine($"Status Code: {response.StatusCode}");
        Console.WriteLine($"Message: {response.Message}");

        // 런타임에 더 많은 속성 추가
        response.Data = new { Id = 1, Name = "John Doe" };

        Console.WriteLine($"Data ID: {response.Data.Id}");
        Console.WriteLine($"Data Name: {response.Data.Name}");
    }
}

이 예제에서:

  • 우리는 DynamicObject를 상속한 ApiResponse 클래스를 생성했습니다.
  • _properties 딕셔너리는 우리의 동적 속성을 저장합니다.
  • TryGetMemberTrySetMember를 재정의하여 이러한 속성을 쉽게 관리할 수 있습니다.

실제 응용 프로그램에서의 이점

  1. API 통합:
    RESTful 서비스와 통합할 때, 요청에 따라 반환되는 JSON 구조가 다를 수 있습니다. DynamicObject를 사용하면 개발자가 엄격한 정의 없이 모델을 쉽게 적응시킬 수 있습니다.
  2. 스크립팅 시나리오:
    게임 엔진과 같이 사용자 정의 스크립트나 구성이 필요한 애플리케이션을 구축할 때, 동적 기능을 사용하면 사용자가 코드를 다시 컴파일하지 않고도 행동을 정의할 수 있는 더 큰 유연성을 제공합니다.
  3. 빠른 프로토타이핑:
    해커톤과 같은 프로젝트에서 데이터 모델에 대한 빠른 반복이 필요한 경우, 동적 객체는 팀이 초기에는 엄격한 타입 정의보다는 기능에 집중할 수 있게 해줍니다.

DynamicObject의 기능을 활용함으로써, C# 개발자는 가독성과 코드베이스의 단순성을 유지하면서도 적응 가능한 구조가 필요한 애플리케이션을 만드는 데 있어 향상된 유연성을 얻을 수 있습니다.

728x90