如何在C#中为动态添加多个同名属性?

时间:2011-12-25 05:50:39

标签: c# c#-4.0 data-structures dynamic

我有dynamic说d。我通过执行以下操作为其添加了一些属性:

((IDictionary<String, Object>)d).Add("Propname", Propvalue);

现在,当我拥有相同名称的属性时,这显然会引发异常。我想允许所有属性,即使它们具有相同的名称。因此,字典是数据结构的错误选择。我在考虑使用C#中的BAG相当于JAVA。我找不到任何东西。解决这个问题的最佳方式是什么?

2 个答案:

答案 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);
}

dynamicIDictionaryLookup无关。 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类而不是词典。