あんまりdynamicって使ったことなかったので作ってみた。
DynamicDictionary.cs
public static class DynamicDictionaryExtension
{
public static dynamic ToDynamic<TValue>(this IDictionary<string, TValue> dict)
{
return new DynamicDictionary<TValue>(dict);
}
}
public class DynamicDictionary<Tvalue> : DynamicObject
{
private IDictionary<string, Tvalue> _dict;
public DynamicDictionary(IDictionary<string,Tvalue> baseDict)
{
_dict = baseDict;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var name = binder.Name.ToLower();
if (_dict.TryGetValue(name, out var value))
{
result = value;
return true;
}
result = null;
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
var name = binder.Name.ToLower();
if (_dict.ContainsKey(name))
{
_dict[name] = (Tvalue) value;
return true;
}
_dict.Add(name,(Tvalue)value);
return true;
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return _dict.Keys;
}
}
使い方としてはこう
Sample.cs
static void Main(string[] args)
{
var dict = new Dictionary<string, string>()
{
{"a", "えー"},
{"b", "びー"},
{"c", "しー"}
};
Console.WriteLine("dict.keys:" + string.Join(",", dict.Keys));
Console.WriteLine("dict.Values:" + string.Join(",", dict.Values));
Console.WriteLine("-----");
var dynamicDict = dict.ToDynamic();
dynamicDict.a = "エー";
dynamicDict.d = "デー";
Console.WriteLine("dict.keys:" + string.Join(",", dict.Keys));
Console.WriteLine("dict.Values:" + string.Join(",", dict.Values));
}
console
dict.keys:a,b,c
dict.Values:えー,びー,しー
-----
dict.keys:a,b,c,d
dict.Values:エー,びー,しー,デー
なんの変哲もひねりもないですが、
dynamic型で受け取る必要がある関係上、varも使えないし、Genericsの型の引数解決も出来ないので
dynamic dynamicDict = new DynamicDictionary<string>(dict);
こう書かざるを得ないのがちょっとアレだったので、拡張メソッド(ToDynamic)を用意。
すると
var dynamicDict = dict.ToDynamic();
こう書ける。というところだけがこだわりポイント。