Ответ 1
Вы взглянули на ExpandoObject?
Из MSDN:
Класс ExpandoObject позволяет добавлять и удалять члены своих экземпляров во время выполнения, а также устанавливать и получать значения этих членов. Этот класс поддерживает динамическое связывание, которое позволяет использовать стандартный синтаксис, например sampleObject.sampleMember, вместо более сложного синтаксиса типа sampleObject.GetAttribute( "sampleMember" ).
Позволяет вам делать такие классные вещи, как:
dynamic dynObject = new ExpandoObject();
dynObject.SomeDynamicProperty = "Hello!";
dynObject.SomeDynamicAction = (msg) =>
{
Console.WriteLine(msg);
};
dynObject.SomeDynamicAction(dynObject.SomeDynamicProperty);
В зависимости от вашего фактического кода вас может больше заинтересовать:
public static dynamic GetDynamicObject(Dictionary<string, object> properties)
{
return new MyDynObject(properties);
}
public sealed class MyDynObject : DynamicObject
{
private readonly Dictionary<string, object> _properties;
public MyDynObject(Dictionary<string, object> properties)
{
_properties = properties;
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return _properties.Keys;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (_properties.ContainsKey(binder.Name))
{
result = _properties[binder.Name];
return true;
}
else
{
result = null;
return false;
}
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (_properties.ContainsKey(binder.Name))
{
_properties[binder.Name] = value;
return true;
}
else
{
return false;
}
}
}
Таким образом вам просто нужно:
var dyn = GetDynamicObject(new Dictionary<string, object>()
{
{"prop1", 12},
});
Console.WriteLine(dyn.prop1);
dyn.prop1 = 150;
Вывод из DynamicObject позволяет вам разработать собственную стратегию для обработки этих динамических запросов членов, Остерегайтесь монстров здесь: компилятор не сможет проверить много ваших динамических вызовов, и вы не получите intellisense, поэтому просто имейте это в виду.