【问题标题】:IList.Add() overwriting existing data [duplicate]IList.Add() 覆盖现有数据
【发布时间】:2013-10-03 20:42:53
【问题描述】:

我在向IList 添加数据时遇到问题,但问题是每次我添加数据时,现有数据都会被当前数据覆盖,我的代码如下所示:

Test test = new Test();
IList<Test> myList = new List<Test>();

foreach (DataRow dataRow in dataTable.Rows)
{
     test.PatientID = Convert.ToInt64(dataRow.ItemArray[0]);
     test.LastName = dataRow.ItemArray[1].ToString();
     test.FirstName = dataRow.ItemArray[2].ToString();
     myList.Add(test);
}

这背后的原因是什么?

【问题讨论】:

  • 您遇到的问题是该测试是引用类型而不是值类型,当您将测试添加到列表时,您正在添加指向内存测试所在的指针,然后运行下一个循环,您在该内存空间中进行更改,覆盖上一个循环中的数据,因此您需要在循环内使用 New 语句为该循环分配新的内存空间以供使用
  • 感谢大家指出我的错误:)
  • 这是一个常见的错误,人们会让你花一些时间来理解这个想法,把它想象成一个文件柜,有两种方法可以使用文件柜,你可以把它放在一张包含所有数据的纸(这是价值类型),或者您可以放入一张纸,其中包含有关如何找到存储在其他地方的原始纸的说明(参考类型)在这种情况下您是添加许多带有说明的纸的副本,但始终在原始纸上进行更改,新声明告诉它让您使用新纸

标签: c# ilist


【解决方案1】:

在循环内移动测试对象的创建

IList<Test> myList = new List<Test>();

foreach (DataRow dataRow in dataTable.Rows)
{   Test test =new Test();
    test.PatientID = Convert.ToInt64(dataRow.ItemArray[0]);
    test.LastName = dataRow.ItemArray[1].ToString();
    test.FirstName = dataRow.ItemArray[2].ToString();
    myList.Add(test);
 }

您当前所做的是在循环内更新test 的同一时刻并一次又一次地添加相同的时刻..

【讨论】:

    【解决方案2】:

    您需要将 Test 对象的创建移到循环内部。原因是对象new Test() 仅被实例化一次,并且对同一对象的引用不断被添加到循环中的列表中。

    【讨论】:

      【解决方案3】:

      因为Test test 是通过引用复制的。您需要将其移动到循环内。

      这样做

      IList<Test> myList = new List<Test>();
      foreach (DataRow dataRow in dataTable.Rows)
      {
           Test test =new Test();
           test.PatientID = Convert.ToInt64(dataRow.ItemArray[0]);
           test.LastName = dataRow.ItemArray[1].ToString();
           test.FirstName = dataRow.ItemArray[2].ToString();
           myList.Add(test);
      }
      

      【讨论】:

        【解决方案4】:

        因为你没有在foreach循环中创建新实例,所以更正代码:

        Test test = null;
        IList<Test> myList = new List<Test>();
        
        foreach (DataRow dataRow in dataTable.Rows)
        {
           test = new Test();
           test.PatientID = Convert.ToInt64(dataRow.ItemArray[0]);
           test.LastName = dataRow.ItemArray[1].ToString();
           test.FirstName = dataRow.ItemArray[2].ToString();
           myList.Add(test);
        }
        

        【讨论】:

          【解决方案5】:

          您一直在使用相同的参考变量(测试)。尝试在循环中创建 new Test()。

          【讨论】:

            【解决方案6】:

            您正在创建Test 的单个实例

            Test test = new Test(); // This is your instance
            IList<Test> myList = new List<Test>();
            
            foreach (DataRow dataRow in dataTable.Rows)
            {
                // Here you change the values of the existing instance each time you loop
                test.PatientID = Convert.ToInt64(dataRow.ItemArray[0]);
                test.LastName = dataRow.ItemArray[1].ToString();
                test.FirstName = dataRow.ItemArray[2].ToString();
                myList.Add(test); // but you are still just adding the same reference to the list multiple times
            }
            

            然后,由于您从未创建新的 Test 实例,因此您将多次向列表添加相同的引用。这意味着您本质上只是一遍又一遍地存储相同的对象:如果您对列表中的一项进行任何更改,它将立即在所有其他项中可见,因为它们本质上是相同的对象

            解决方案是将test的实例化移动到循环内

            IList<Test> myList = new List<Test>();
            
            foreach (DataRow dataRow in dataTable.Rows)
            {
                Test test = new Test(); // Each loop iteration will now create a new instance of Test
                test.PatientID = Convert.ToInt64(dataRow.ItemArray[0]);
                test.LastName = dataRow.ItemArray[1].ToString();
                test.FirstName = dataRow.ItemArray[2].ToString();
                myList.Add(test);
            }
            

            如果您需要更好地理解这一点,请查看 .NET 中的引用和值类型以及通过引用/值传递

            .NET 中的值和引用类型: http://msdn.microsoft.com/en-us/library/t63sy5hs.aspx

            关于维基百科指针的一些信息 http://en.wikipedia.org/wiki/Pointer_(computer_programming)

            【讨论】:

              猜你喜欢
              • 2014-04-06
              • 2012-04-24
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-08-23
              • 1970-01-01
              • 2022-08-20
              • 1970-01-01
              相关资源
              最近更新 更多