我有dynamic
说d。我通过执行以下操作为其添加了一些属性:
((IDictionary<String, Object>)d).Add("Propname", Propvalue);
现在,当我拥有相同名称的属性时,这显然会引发异常。我想允许所有属性,即使它们具有相同的名称。因此,字典是数据结构的错误选择。我在考虑使用C#中的BAG相当于JAVA。我找不到任何东西。解决这个问题的最佳方式是什么?
答案 0 :(得分:5)
您似乎完全混合了几个概念。
dynamic
是一个触发器,它使编译器生成后期绑定代码。虽然它没有在编译时验证,但它遵循与普通c#代码相同的规则。它不能具有多值属性(你可以在.NET的任何地方拥有它们吗?)。唯一的方法是拥有一个集合值属性并为集合添加新值。像这样:
dynamic obj = new ExpandoObject();
obj.SomeProperty = new List<object>();
obj.SomeProperty.Add(SomeValue);
obj.SomeProperty.Add(AnotherValue);
foreach(var somePropertyValue in obj.SomeProperty)
{
DoSmth(somePropertyValue);
}
dynamic
与IDictionary
或Lookup
无关。 dynamic
变量可以是任意对象,例如int
值。如果你使用dynamic
,那么你将它强加到IDictionary
界面是非常奇怪的。只需致电Add
,DLR将为您解决方法(就像我上面所做的那样)。
只有在与动态环境(脚本语言,COM等)进行互操作时,才应使用dynamic
。如果你只使用c#代码 - 扔掉所有动态的东西并使用常规的.NET集合。它将由编译器进行静态验证,并且工作得更快。
例如,您可以使用Dictionary<string, ICollection<object>>
来创建动态词典:
var dictionary = new Dictionary<string, ICollection<object>>();
dictionary["SomeProperty"] = new List<object>();
dictionary["SomeProperty"].Add(SomeValue);
dictionary["SomeProperty"].Add(AnotherValue);
foreach(var somePropertyValue in dictionary["SomeProperty"])
{
DoSmth(somePropertyValue);
}
<强>更新强>
哦,是的,您可以尝试创建自己的DynamicObject
实现,在实现属性分配时将值放入包中,而不是覆盖现有值。具体来说,您应该覆盖TrySetMember method。但首先想想你是否真的需要所有这些复杂的东西。
答案 1 :(得分:4)
不太确定您希望预期的行为是什么,但如果您希望在同一属性名称下保存多于1个项目,则可以使用System.Linq.Lookup类而不是词典。