从另一个集合中访问struct集合属性

时间:2012-09-19 09:17:49

标签: c# collections

我有一个需要存储在集合中的结构。 struct有一个返回Dictionary的属性。

public struct Item
{
    private IDictionary<string, string> values;
    public IDictionary<string, string> Values
    {
        get
        {
            return this.values ?? (this.values = new Dictionary<string, string>());
        }
    }
}

public class ItemCollection : Collection<Item> {}

测试时我发现如果我将项目添加到集合中然后尝试访问字典,那么结构值属性永远不会更新。

 var collection = new ItemCollection { new Item() }; // pre-loaded with an item
 collection[0].Values.Add("myKey", "myValue");
 Trace.WriteLine(collection[0].Values["myKey"]); // KeyNotFoundException here

但是,如果我先加载项目然后将其添加到集合中,则会保留值字段。

 var collection = new ItemCollection();
 var item = new Item();
 item.Values.Add("myKey", "myValue");
 collection.Add(item);
 Trace.WriteLine(collection[0].Values["myKey"]); // ok

我已经确定结构是这种类型的错误选项,并且在使用类时问题不会发生,但我很好奇这两种方法之间有什么不同。任何人都可以解释发生了什么吗?

3 个答案:

答案 0 :(得分:2)

将结构更改为类:

public class Item {}

现在我不熟悉内部,但结构是值类型而类是引用类型,我相信有逻辑可以解释为什么在运行第一个代码示例时会出现异常

我希望有人可以介入给你一个更全面的答案,但就目前而言,只需将结构更改为一个类。

答案 1 :(得分:1)

“项目”是一个有价值的项目。这意味着,如果您访问该集合,则会创建一个副本。所有操作都在该副本上完成

 collection[0].Values.Add("myKey", "myValue");

这里是第一个复制项目,然后Value get访问器创建一个新实例,该实例存储在副本中,然后添加该项目。然后副本被销毁。

解决方法是直接在创建struct

时创建Values字典
public struct Item
{
    private IDictionary<string, string> values = new Dictionary<string, string>();
    public IDictionary<string, string> Values
    {
        get
        {
            return this.values;
        }
    }
}

如果您访问该集合,则会制作副本。但是这个副本包含与原始字典相同的值字典的引用。所以修改了原始字典

答案 2 :(得分:1)

如前所述,将struct Item更改为class Item。当您使用struct时,表达式collection[0]不会返回对new ItemCollection { new Item() }中创建的对象的引用,而是创建它的副本并将其提供给您。