c#中的通用容器修改容器外容器元素的问题

时间:2011-03-18 03:10:37

标签: c# generics scope containers

我在c#编程中遇到问题,需要帮助,  当我在c#中创建一个通用容器并修改它在列表之外的一个元素时它也被修改了,而我想保留列表的元素,因为它是

我搜索过容器范围或引用但我什么都没找到 顺便说一下,我之前多次遇到过这个问题,我用复制构造函数解决了以下问题

List<Object> list=new List<Object>();
list.Add(new Object(object) );

但在这种情况下,我的解决方案无效

 List<List<Object>> allObjects = new List<List<Object>>(1000);
 List<Object> object = new List<Object>();

 for (int i = 0; i < 1000; i++)
 {
            object = new List<Object>();
            //some code here that fill  object list
            allObjects.Add(object);

 }//after filling all the 1000 elements in allObjects list,all the elements of the   //list are 1000 elements with the same value of the last object has been inserted

我的错误解决方案没有问题

 List<List<Object>> allObjects = new List<List<Object>>(1000);
 List<Object> object = new List<Object>();

 for (int i = 0; i < 1000; i++)
 {
            object = new List<Object>();
            //some code here that fill object list
            allObjects.Add(new List<Object>(object));

 }

提前致谢

5 个答案:

答案 0 :(得分:1)

C#中的对象是引用类型。当您创建一个新对象时,.net会在堆上为该对象分配内存,该变量本身实际上是指向该对象的指针。

列表“通用容器”保留对象的引用列表,而不是对象本身。当您从列表中获取对象时,即:var x = list [10],您实际上只是获取对列表引用的同一对象的引用。通过修改对象,更改也将反映在列表中包含的对象中。

要“修改列表外的对象”,并且没有在列表中的对象上显示该更改,您必须复制该对象;有几种方法可以做到这一点,具体取决于你的对象是什么。

为了这个例子,如果你选择使用结构类型而不是基础'对象',你将体验到你正在寻找的行为。 c#中的结构不是引用类型。

希望我没有把你弄糊涂了?

阅读完评论后,请尝试这样的事情。

List<object> list2 = new List<object>();
for(int i = 0; i < 1000; i++)
{
   List<object>list1 = new List<object>();
   for(int j = 0; j< 1000; j++)
   {
      list1.Add( "something" + j);
   }
   list2.Add(list1);
}

以上将创建一个包含1000个1000长度列表的列表。

答案 1 :(得分:0)

以下内容:

object = new List<Object>();
allObjects.Add(object);

相当于:

allObjects.Add(new List<Object>());

也相当于:

object = new List<Object>();
allObjects.Add(new List<Object>(object));

在最后一种情况下,您正在创建一个空列表,然后创建另一个用第一个列表填充的空列表。

修改:我想通过在此处留​​下此链接来添加Jon所说的内容:http://www.yoda.arachsys.com/csharp/parameters.html

这应该可以帮助您理解值和引用类型之间的差异,因为我认为这是您感到困惑的地方。

答案 2 :(得分:0)

在评论中你说:

//after filling all the 1000 elements in allObjects list,all the elements of the
//list are 1000 elements with the same value of the last object has been inserted

但如果你尝试一些简单的事情:

List<List<int>> allObjects = new List<List<int>>(10);
for (int i = 0; i < 10; i++)
{
    var obj = new List<int>();
    obj.Add(i);
    allObjects.Add(obj);
}

并检查调试器中列表的值,您将看到每个子列表都有一个值为i的元素(从0到9)。 因此,在我看来,您的代码正在做正确的事情。

当您尝试访问列表中的这些元素并且您只是真正访问最后一个元素时,可能会出现问题。

或许你的Object类是一个单例类型的类,它只能有一个实例(可能不仅仅是在不知道任何关于Object的信息的情况下想到的东西)。

答案 3 :(得分:0)

我认为你的问题在“这里的一些代码填充对象列表”中。您放入内部List的对象(您有点混淆地称之为“object”)是引用类型,您可能会将对相同对象的引用放入每个内部列表中。因此,即使内部List本身是唯一的实例,它们内部的对象也不是。

答案 4 :(得分:0)

感谢所有人的鼓舞人心的答案&amp;对不起4干扰 实际上我发现问题在于用重复数据填充内部列表本身(使用随机数生成器并重复数据) 所以这不是我想的引用问题