我试图想办法利用动态类型来提供其成员的自然使用,但最终来自Dictionary<string, string>
对象。但是,我希望能够定义如何解析给定属性的规则。这可能吗?
我想要这样的东西。
var dynamicCollection = new MyDyanmicType();
dynamicCollection.Build(/*some dictionary*/); // or just implement an implicit operator
dynamicCollection.MemberProperty; // <-- this should let me search the dictionary how I want for some form of the string "MemberProperty"
dynamicCollection.PropertyThatDoesntExist; // <-- this should give me an opportunity to exhaust my resolution and throw back a custom exception that I choose
用例是我有一些由产品管理人员在数据库中动态设置的字段。不幸的是,我需要防范人为错误的波动。鉴于上述情况,有人可能会输入memberProperty,Member Property等,因此我需要控制如何查找声明的成员,同时保持对普通POCO的清洁使用。
我面临的问题是我有一个样本字典代码的TON,我试图摆脱它,这将允许我摆脱一些相当讨厌和冗长的运行时检查。
答案 0 :(得分:0)
这比我想象的要容易得多。解决方案看起来像这样。
public class AddOnBag : DynamicObject
{
private Dictionary<string, string> _addOns;
public static AddOnBag BuildBag(Dictionary<string, string> dict)
{
var bag = new AddOnBag {_addOns = dict};
return bag;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var addOn = LookupAddOn(binder.Name);
result = addOn.Value;
return addOn.Key != null;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
var addOn = LookupAddOn(binder.Name);
if (addOn.Key == null)
{
return false;
}
_addOns[addOn.Key] = value.ToString();
return true;
}
private KeyValuePair<string, string> LookupAddOn(string name)
{
var addOn = _addOns.FirstOrDefault(pair =>
{
var stripped = pair.Key.Replace(" ", string.Empty);
var attempted = name;
return string.Equals(stripped, attempted, StringComparison.OrdinalIgnoreCase);
});
return addOn;
}
}
另外,事实证明,微软提供的示例非常接近于此。
用法只需要dynamic
关键字。另外,如果向您创建的类添加方法,CLR足够智能,可以将调用路由到预期的方法,而不是TryGetMember
或TryInvokeMember
。