C#System.Collections.Generic.List <t>?</t>中的错误

时间:2014-03-25 06:32:15

标签: c# list

我正在编写一个简单的代码来从文本文件中读取一些数据并存储在C#列表中,但是存在问题。如果问题出在我身边或是图书馆,请提供帮助。我写了以下功能:

public List<EmpBO> ReadData()
        {
            EmpBO temp = new EmpBO();
            List<EmpBO> lis = new List<EmpBO>(100);
            string[] tokens;
            string data;
            StreamReader sw = new StreamReader(new FileStream("emp.txt",FileMode.OpenOrCreate));
            int ind = 0;
            while ((data = sw.ReadLine())!=null)
            {
                Console.WriteLine("Reading " + data);
                tokens = data.Split(';');
                temp.Id = int.Parse(tokens[0]);
                temp.Name = tokens[1];
                temp.Salary = double.Parse(tokens[2]);
                temp.Br = double.Parse(tokens[3]);
                temp.Tax = double.Parse(tokens[4]);
                temp.Designation = tokens[5];
                //lis.Add(temp);
                lis.Insert(ind,temp);
                ind++;

            }
            sw.Close();
            Console.WriteLine("Read this material and returning list");
            for (int i = 0; i < lis.Count; i++)
            {
                Console.WriteLine("" + (lis.ElementAt(i)).Name);
            }
                //foreach (EmpBO ob in lis)
                //{
                //    Console.WriteLine("" + ob.Id + ob.Name);
                //}
                return lis;
        }

文件emp.txt包含:

  

1;艾哈迈德; 100000; 20; 1000;经理
  2;比拉尔; 200000; 15; 2000; CEO

现在您可以看到在while循环中,我已经显示了StreamReader读取的内容,在这种情况下它会进行2次迭代并显示。

  

阅读1; Ahmed; 100000; 20; 1000;经理
  阅读2; Bilal; 200000; 15; 2000; ceo

正如您所见,我将此信息保存在temp中并插入列表中。
在while循环结束后,当我遍历列表以了解存储在其中的内容时,它会显示:

  

阅读此资料并返回清单
  比拉尔
  BILAL

好吧,第二条记录存储在列表中两次,第一条记录不存在。这似乎是什么问题?我也使用了Add()方法,并且foreach循环用于遍历列表,因为你可以看到它被注释掉但是结果是相同的......请帮忙

5 个答案:

答案 0 :(得分:8)

移动此行

EmpBO temp = new EmpBO();

进入while循环,使其看起来像

while ((data = sw.ReadLine())!=null){
  EmpBO temp = new EmpBO();
  Console.WriteLine("Reading " + data);
  tokens = data.Split(';');
  temp.Id = int.Parse(tokens[0]);
  temp.Name = tokens[1];
  temp.Salary = double.Parse(tokens[2]);
  temp.Br = double.Parse(tokens[3]);
  temp.Tax = double.Parse(tokens[4]);
  temp.Designation = tokens[5];
  //lis.Add(temp);
  lis.Insert(ind,temp);
  ind++;

}

您不是为每个条目创建新的EmpBO,而是使用读取的值覆盖同一个对象并将其再次添加到列表中。

效果是您将相同的对象多次添加到列表中。

答案 1 :(得分:2)

在您的代码中,您只创建了一次EmpBO对象。在第二次迭代中,您将修改同一对象中的值。你必须在while循环中为EmpBO创建实例,如下所示。

while ((data = sw.ReadLine())!=null)
{
Console.WriteLine("Reading " + data);
tokens = data.Split(';');
EmpBO temp = new EmpBO();
temp.Id = int.Parse(tokens[0]);
temp.Name = tokens[1];
temp.Salary = double.Parse(tokens[2]);
temp.Br = double.Parse(tokens[3]);
temp.Tax = double.Parse(tokens[4]);
temp.Designation = tokens[5];
//lis.Add(temp);
lis.Insert(ind,temp);
ind++;
}

答案 2 :(得分:1)

这不是问题的直接答案,但您的代码还有其他问题。

FileStreamStreamReader都应在使用后进行处理。

或者,您可以像这样编写代码:

public List<EmpBO> ReadData()
{
    return File
        .ReadAllLines("emp.txt")
        .Select(data =>
        {
            var tokens = data.Split(';');
            return new EmpBO()
            {
                Id = int.Parse(tokens[0]),
                Name = tokens[1],
                Salary = double.Parse(tokens[2]),
                Br = double.Parse(tokens[3]),
                Tax = double.Parse(tokens[4]),
                Designation = tokens[5],
            };
        })
        .ToList();
}

希望这应该更容易。

答案 3 :(得分:0)

您已将相同的对象插入两次。你必须在循环中创建一个新对象,否则你将覆盖每次迭代的属性,并简单地反复引用同一个对象。可以安全地假设BCL类上的标准操作正常工作或者正如Eric Lippert所说的Maybe there's something wrong with the universe but probably not

您只需将循环的开头更改为:

while ((data = sw.ReadLine())!=null)
{
    EmpBO temp = new EmpBO();

答案 4 :(得分:0)

如果您尝试在列表中添加两次相同的对象,它将覆盖第一次输入的值,并且仅显示第二个对象的值,但是两次 例如:获取一个列表,在其中添加一个对象。修改该对象,再次添加它。 当您尝试打印值时,您将获得最后一个对象的值

ob1.a=5;
list1.add(ob1);

// list1 [0] - &gt; a - &gt; 5

ob1.a=7;
list1.add(ob1);

// list1 [0] ---&gt; a ---&gt; 7 list1 [1] ---&gt; a ---&gt; 7