
빌 와그너, ⌜More Effective C# 2판⌟, 김완섭 옮김, 한빛미디어, 2019
이 포스팅은 ⌜More Effective C# 2판⌟의 내용을 기반으로 작성되었습니다.
동적 프로그래밍의 큰 장점 하나는 런타임에 public 인터페이스가 바뀌는 타입을 만들 수 있다는 것이다.
동적 능력을 갖춘 고유의 타입을 만들 수 있다.
동적능력을 가지는 타입을 만드는 가장 쉬운 방법은 System.Dynamic.DynamicObject를 상속하는 것이다.
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를 구현해서 동적 딕셔너리를 만들면 된다.
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를 구현하자
단, 구현이 쉽지 않고, 동적 타입은 성능을 다소 떨어뜨린다.