Problem with ArrayList

M

Magus

I'm about to bash my head against the wall. I can't seam to figure out when calling List.Add(string[]) it seems to change every value in the List.

My code as follows:

private List<string[]> ReadUpdateHash(string URL)
{
string[] values = new string[2];
List<string[]> hashes = new List<string[]>();
using (XmlReader reader = XmlReader.Create(WebRequest.Create(URL).GetResponse().GetResponseStream()))
{
while (reader.Read())
{
if (reader.IsStartElement()) // Is start element
{
if (!reader.IsEmptyElement)
{
switch (reader.Name)
{
case "Name":
Array.Clear(values, 0, 2); // Clear if first element
if (reader.Read()) { values[0] = reader.Value; }
break;
case "Hash":
if (reader.Read()) { values[1] = reader.Value; }
hashes.Add(values);
break;
}
}
}
}
}
return hashes;
}

And I'm using the following to call it:

// Get the updated hashes stored online
List<string[]> onlineHashes = new List<string[]>();
onlineHashes = ReadUpdateHash("http://www.gamersjudgement.com/OCTGN/Hash.XML");

The values that List returns all contain the same values as the last array added.
 
J

Jeff Johnson

You keep re-using the string array. First get rid of this line:
case "Name":
-->> Array.Clear(values, 0, 2); // Clear if first element
if (reader.Read()) { values[0] = reader.Value; }
break;

and add this:
case "Hash":
if (reader.Read()) { values[1] = reader.Value; }
hashes.Add(values); values = new string[2];
break;
 
A

Arne Vajhøj

I'm about to bash my head against the wall. I can't seam to figure out when calling List.Add(string[]) it seems to change every value in the List.

My code as follows:

private List<string[]> ReadUpdateHash(string URL)
{
string[] values = new string[2];
List<string[]> hashes = new List<string[]>();
using (XmlReader reader = XmlReader.Create(WebRequest.Create(URL).GetResponse().GetResponseStream()))
{
while (reader.Read())
{
if (reader.IsStartElement()) // Is start element
{
if (!reader.IsEmptyElement)
{
switch (reader.Name)
{
case "Name":
Array.Clear(values, 0, 2); // Clear if first element
if (reader.Read()) { values[0] = reader.Value; }
break;
case "Hash":
if (reader.Read()) { values[1] = reader.Value; }
hashes.Add(values);
break;
}
}
}
}
}
return hashes;
}

And I'm using the following to call it:

// Get the updated hashes stored online
List<string[]> onlineHashes = new List<string[]>();
onlineHashes = ReadUpdateHash("http://www.gamersjudgement.com/OCTGN/Hash.XML");

The values that List returns all contain the same values as the last array added.

Jeff has already explained both the problem in your code and a
simple fix.

But let m show you two slightly different approaches that may
inspire you.

First: if the XML data are small enough to be in memory, then
XDocument would be much simpler than XmlReader.

Example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace E
{
public class UpdateFile
{
public string Name { get; set; }
public string Hash { get; set; }
}
public class Program
{
public static void Main(string[] args)
{
XDocument doc =
XDocument.Load("http://www.gamersjudgement.com/OCTGN/Hash.XML");
List<UpdateFile> hashes =
doc.Root.Elements("Files").Select(f => new UpdateFile{
Name=f.Element("Name").Value, Hash=f.Element("Hash").Value }).ToList();
foreach(UpdateFile uf in hashes)
{
Console.WriteLine(uf.Name + " : " + uf.Hash);
}
Console.ReadKey();
}
}
}

But even if XmlReader is necesarry I would structure the
parsing a bit differently.

Example:

using System;
using System.Collections.Generic;
using System.Xml;

namespace E
{
public class UpdateFile
{
public string Name { get; set; }
public string Hash { get; set; }
}
public class Program
{
public static void Main(string[] args)
{
List<UpdateFile> hashes = new List<UpdateFile>();
XmlReader rdr =
XmlReader.Create("http://www.gamersjudgement.com/OCTGN/Hash.XML");
string name = null;
string hash = null;
while(rdr.Read())
{
if(rdr.NodeType == XmlNodeType.Element)
{
if(rdr.Name == "Files")
{
name = "";
hash = "";
}
else if(rdr.Name == "Name")
{
name = rdr.ReadString();
}
else if(rdr.Name == "Hash")
{
hash = rdr.ReadString();
}
}
else if(rdr.NodeType == XmlNodeType.EndElement)
{
if(rdr.Name == "Files")
{
hashes.Add(new UpdateFile{ Name=name, Hash=hash });
}
}
}
foreach(UpdateFile uf in hashes)
{
Console.WriteLine(uf.Name + " : " + uf.Hash);
}
Console.ReadKey();
}
}
}

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top