[More Effective C#] 5장 - Item 45: 데이터 주도 동적 타입에는 DynamicObject나 IDynamicMetaObjectProvider를 사용하라

SY·2023년 11월 15일

More Effective C#

목록 보기
44/46
post-thumbnail

빌 와그너, ⌜More Effective C# 2판⌟, 김완섭 옮김, 한빛미디어, 2019
이 포스팅은 ⌜More Effective C# 2판⌟의 내용을 기반으로 작성되었습니다.


아이템 45: 데이터 주도 동적 타입에는 DynamicObject나 IDynamicMetaObjectProvider를 사용하라



동적 프로그래밍의 큰 장점 하나는 런타임에 public 인터페이스가 바뀌는 타입을 만들 수 있다는 것이다.
동적 능력을 갖춘 고유의 타입을 만들 수 있다.

동적능력을 가지는 타입을 만드는 가장 쉬운 방법은 System.Dynamic.DynamicObject를 상속하는 것이다.


DynamicObject

  • 런타임에 동적 동작을 지정하기 위한 기본 클래스를 제공한다.
  • 유연한 Customization을 위한 고급 dynamic 기능을 지원한다.
  • DynamicObject를 상속 받고, 3개의 methods를 override 해야 한다.
    • TryGetMember, TrySetMember, TryInvokeMember
  • 인덱서, 메서드, 생성자, 단항 연산자, 이항 연산자 등의 동적 호출을 처리하는 비슷한 메서드들을 갖고 있어, 이 멤버들 중 원하는 것을 재정의하여 자신만의 동적 멤버를 만들 수 있다.
  • DynamicPropertyBag(동적 속성 모음)을 구현하는 예시 코드
    • TryGetMember는 속성의 이름을 확인하여 있으면 반환한다.
class DynamicPropertyBag : DynamicObject
{
	private Dictionary<string, object> storage = new Dictionary<string, object>();
    
    public override bool TryGetMember(GetMemberBinder binder, out objectResult)
    {
    	if(storage.ContainsKey(binder.Name))
        {
        	result = storage[binder.Name];
            return true;
        }
        result = null;
        
        return false;     
    }
    
    public override bool TrySetMember(SetMemberBinder binder, object value
    {
    	string key = binder.Name;
        if(storage.ContainsKey(key))
        	storage[key] = value;
        else
        	storage.Add(key, value);
        
        return true;
    }
    
    public override string ToString()
    {
    	StringWriter message = new StringWriter();
        foreach(var item in storage)
        	message.WriteLine($"{item.Key}:\t{item.Value}");
            
        return message.ToString();
    }
}



만약 다른 베이스 클래스를 상속해야 해서 DynamicObject를 상속할 수 없다면, 동적 타입을 직접 만들어야 한다.

IDynamicMetaObjectProvider를 구현해서 동적 딕셔너리를 만들면 된다.


IDynamicMetaObjectProvider

  • IDynamicMetaObjectProvider를 구현하려면, GetMetaObject라는 메서드 하나만 구현하면 된다.
  • DynamicDictionary 구현 예시
class DynamicDictionary : IDynamicMetaObjectProvider
{
	DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(
    	System.Linq.Expressions.Expression parameter)
     {
     	return new DynamicDictionaryMetaObject(parameter, this);
     }
     
     private Dictionary<string, object> storage = new Dictionary<string, object>();
     
     public object SetDictionaryEntry(string key, object value)
     {
     	// 코드 생략
     }
     
     public object GetDictionaryEntry(string key)
     {
     	// 코드 생략
     }
     
     public override string ToString()
     {
     	// 코드 생략 
        // StringWriter안에 key,value를 string으로 담아 return
     }
}


동적 타입을 만들어야 한다면 가장 먼저 System.Dynamic.DynamicObject를 상속 하자.
다른 베이스 클래스를 사용해야 해서 어쩔 수 없다면 IDynamicMetaObjectProvider를 구현하자
단, 구현이 쉽지 않고, 동적 타입은 성능을 다소 떨어뜨린다.

profile
게임 개발 공부

0개의 댓글